DSP

灰度直方图的原理和计算

2019-07-13 19:15发布

一、灰度直方图的认识

  我们平时看到的灰度图像是由0到255个像素组成的,像素是组成图像的基本单位,灰度直方图就是灰度图像素值的直观体现,其中bins就是衣服灰度图直方图的条数。                                                   
                                     

二、程序1

原理大家去百度吧,在这就不具体说了。 程序中涉及到血多opencv函数,我下面简单介绍一些: 1.计算直方图: void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray   hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=   false );分别表示:输入图像、输入图像的维数、输入图像的通道数、掩膜、输出直方图、输出维数、输出直方图的bins数等。 2.球直方图最大、最小块,也即是找最大和最小的bins void minMaxLoc( const Mat& src,double* minVal,double* maxVal=0,Point* minLoc=0,Point* maxLoc=0,const Mat& mask=Mat() ); 3.在图像中画矩形 void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 );分别表示:原图像、左上角坐标、右下角坐标等

好,开始贴代码:
#include #include #include using namespace cv; using namespace std; int main() { Mat src, gray; src = imread("D:\vvoo\lena.jpg"); cvtColor(src, gray, CV_RGB2GRAY); int bins = 256;//一维直方图bins int hist_size[] = { bins }; float range[] = { 0, 256 };//直方图每一个bins的范围 const float* ranges[] = { range }; MatND hist;//输出直方图 int channels[] = { 0 };//一维通道 //创建并计算直方图 calcHist(&gray, 1, channels, Mat(), // do not use mask hist, //输出直方图 1, hist_size, ranges, true, // the histogram is uniform false); double max_val; minMaxLoc(hist, 0, &max_val, 0, 0);//找出最大的bins值 int scale = 2;//bins之间的距离为2 int hist_height = 300;//输出直方图的高度 Mat hist_img = Mat::zeros(hist_height, bins*scale, CV_8UC3);//定义hist_img的矩阵,高度为hist_height,宽度为bins*scale for (int i = 0; i(i); int intensity = cvRound(bin_val*hist_height / max_val); //归一化,要绘制的高度,从上往下数 rectangle(hist_img, Point(i*scale, hist_height/* - 1*/), Point((i + 1)*scale - 1, hist_height - intensity), CV_RGB(0, 255, 255)); } imshow("Source", src); imshow("Gray Histogram", hist_img); waitKey(500000); return 0; }
运行结果: 原图
直方图

三、程序2(滑动块控制量化位数)

是对程序1进行稍微更改: 滑动块函数: CreateTrackbar( const char* trackbar_name, //滑动条的名称 const char* window_name, //窗口的名称,滑动条不会遮挡图像 int* value, //当滑动条被拖到时,OpenCV会自动将当前位置所代表的值传给指针指向的整数 int count, //滑动条所能达到的最大值 CvTrackbarCallback on_change //可选的回调函数,回调函数可参见http://wapedia.mobi/zhtrad/回调函数 ); 程序2: #include #include using namespace cv; using namespace std; Mat srcImage, gray; int bins = 200; #define hist_height 500//输出直方图的高度 #define hist_width 800 static void showHelpText(); static void HIST(int, void*); int main() { showHelpText(); system("color 4d"); srcImage = imread("D:\vvoo\lena.jpg"); if (!srcImage.data) { cout << "the image is error !" << endl; return 0; } namedWindow("srcIamge"); imshow("srcIamge", srcImage); cvtColor(srcImage, gray, CV_RGB2GRAY); //调用 createTrackbar("bins", "srcIamge", &bins, 256, HIST); HIST(0, 0); while ((char(waitKey(1)) != 'q'))//q键退出 { } waitKey(0); return 0; } static void HIST(int, void*) { int hist_size[] = { bins }; float range[] = { 0, 256 };//直方图每一个bins的范围 const float* ranges[] = { range }; MatND hist;//输出直方图 int channels[] = { 0 };//一维通道 //创建并计算直方图 calcHist(&gray, 1, channels, Mat(), // do not use mask hist, //输出直方图 1, hist_size, ranges, true, // the histogram is uniform false); double max_val; minMaxLoc(hist, 0, &max_val, 0, 0);//找出最大的bins值 Mat hist_img = Mat::zeros(hist_height, hist_width, CV_8UC3);//定义hist_img的矩阵 double bin_w = (double)hist_width / bins; //bins为直方图条的个数,则 bin_w 为条的宽度 for (int i = 0; i(i); int intensity = cvRound(bin_val*hist_height / max_val); //归一化,要绘制的高度,从上往下数 rectangle(hist_img, Point(i*bin_w, hist_height), Point((i + 1)*bin_w, hist_height - intensity), CV_RGB(255, 0, 255)); } imshow("一维直方图", hist_img); } static void showHelpText() { cout << "通过滑块调节直方图量化的条数" << endl; }
结果:

四、参考资料

1.点击打开链接
http://blog.csdn.net/sxhelijian/article/details/8042507
2.灰度直方图