opencv图像直方图的计算及绘制
来源:互联网 发布:工业控制网络组成 编辑:程序博客网 时间:2024/04/29 03:40
OpenCV 中提供了 calcHist 函数来计算图像直方图,其函数原型是:
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )各个参数的含义如下:
images:输入的图像的指针,可以是多幅图像,但要求所有的图像必须有同样的深度(CV_8U or CV_32F)。
nimages:输入的图像的个数。
channels:计算直方图的 channels 的数组。
mask:掩码,如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和输入的图像的大小相同,值非 0 的点将用来计算直方图。
hist:输出参数,计算出来的直方图。
dims:直方图的维数,不能大于 CV_MAX_DIMS 。
histSize:在每一维上直方图的元素个数。
ranges:直方图每一维的范围,ranges 是指向数组的数组,它指向的那些数组为 ranges 的元素,元素大小也就是这些数组的长度。
如果参数uniform为 true,这此时的ranges 里元素的大小为 2(也就是说 ranges 指向一系列长度为 2 的数组);如果参数 uniform 为 false,则此时每一维的坐标值不一定是均匀的,需要人为指定。
uniform: 如果为 true 的话,则说明所需计算的直方图的每一维按照它的范围和尺寸大小均匀取值;如果为 false 的话,说明直方图的每一维不是均匀分布取值的,参考参数 ranges 的解释。
accumulate: 表示是否对传入的 hist 清零。不清零的话可以将多幅图像的直方图累加。
#include<opencv2/opencv.hpp> #include<iostream> #include<vector> using namespace cv; using namespace std; int main() { Mat srcImage = imread("E://IM_VIDEO//kobe.jpg"); imshow("ScrImage", srcImage); int channels = 0; MatND dstHist; int histSize[] = { 256 }; //如果写成int histSize = 256;调用计算直方图的函数的时,该变量需写成&histSize float midRanges[] = { 0, 256 }; const float *ranges[] = { midRanges }; calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false); //绘制直方图,首先先创建一个黑底的图像,为了可以显示彩色,所以该绘制图像是一个8位的3通道图像 Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3); //任何一个图像的某个像素的总个数有可能会很多,甚至超出所定义的图像的尺寸, //所以需要先对个数进行范围的限制,用minMaxLoc函数来得到计算直方图后的像素的最大个数 double g_dHistMaxValue; minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0); //将像素的个数整合到图像的最大范围内 for (int i = 0; i < 256; i++) { int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue); line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - value), Scalar(0, 0, 255)); } imshow("hist", drawImage); waitKey(0); return 0; }运行结果如下:
实例二:将计算和绘制直方图写成函数
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; // 得到图像的直方图 MatND getHistogram(Mat &image) { MatND hist; int channels[] = {0}; int dims = 1; int histSize[] = {256}; float granges[] = {0, 255}; const float *ranges[] = {granges}; calcHist(&image, 1, channels, Mat(), hist, dims, histSize, ranges); return hist; } // 将图像直方图展示出来 Mat getHistogramImage(Mat &image) { MatND hist = getHistogram(image); Mat showImage(256,256, CV_8U,Scalar(0)); int i; double maxValue = 0; minMaxLoc(hist, 0, &maxValue, 0, 0); for(i = 0; i < 256; i++) { float value = hist.at<float>(i); int intensity = saturate_cast<int>(256 - 256* (value/maxValue)); rectangle(showImage, Point(i,256 - 1), Point((i+1)-1, intensity), Scalar(255)); } return showImage; } //主函数 int main() { Mat image = imread("E://IM_VIDEO//kobe.jpg"); if(!image.data) { cout << "fail to load the image" << endl; return 0; } Mat showImage = getHistogramImage(image); namedWindow("image"); imshow("image", image); namedWindow("showImage"); imshow("showImage", showImage); waitKey(0); return 0; }运行结果:
实例三:计算和绘制多通道图像的直方图
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main( int argc, char** argv ) { Mat src, dst; src = imread("E://IM_VIDEO//kobe.jpg"); if( !src.data ) { return -1; } vector<Mat> rgb_planes; split( src, rgb_planes ); int histSize = 255; float range[] = { 0, 255 } ; const float* histRange = { range }; bool uniform = true; bool accumulate = false; Mat r_hist, g_hist, b_hist; // 计算直方图: calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); // 创建直方图画布 int hist_w = 400; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize ); Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); // 将直方图归一化到范围 [ 0, histImage.rows ] normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); // 在直方图画布上画出直方图 for( int i = 1; i < histSize; i++ ) { line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ), Scalar( 0, 0, 255), 2, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ), Scalar( 0, 255, 0), 2, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 ); } /// 显示直方图 namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE ); imshow("calcHist Demo", histImage ); waitKey(0); return 0; }运行结果如下:
参考:
http://blog.csdn.net/liyuanbhu/article/details/50708912
http://blog.csdn.net/qq_23880193/article/details/49669297
http://blog.csdn.net/zhouzhouzf/article/details/9272299
http://blog.csdn.net/lu597203933/article/details/17061173
0 0
- opencv图像直方图的计算及绘制
- 【OpenCV】绘制图像的直方图
- OpenCV-统计图像的直方图,绘制直方图
- opencv之直方图计算及绘制
- opencv 绘制图像直方图
- opencv 图像直方图绘制
- Opencv绘制灰度/彩色图像的直方图及直方图的均衡化实例及源代码
- OpenCV-绘制图像的像素直方图-Histogram
- OpenCV【4】---calcHist 计算图像的直方图
- OpenCV 学习(计算图像的直方图)
- opencv学习之(五)-直方图计算和绘制图像直方图
- opencv学习之(五)-直方图计算和绘制图像直方图
- calcHist()计算图像直方图opencv
- OpenCV之图像直方图计算
- OpenCV入门(二十一)-- 绘制彩色图像的直方图
- Opencv学习笔记——绘制图像的像素直方图
- OpenCV:绘制图像的BGR三通道直方图
- OpenCV之单通道图像的直方图绘制
- PCB学习(二)
- Spring注解
- 非关系型内存数据库Redis的基本介绍
- 无缓冲访问文件
- C程序(2)
- opencv图像直方图的计算及绘制
- Oracle快照及dblink使用(两台服务器数据同步)
- MySQL 数据库使用命令大全
- 一个小作品
- android studio Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' t
- 【JZOJ 3854】 分组
- 设计算法之分治法
- Spring_7_Bean 的作用域
- prim最小生成树