opencv2 直方图 calchist函数

来源:互联网 发布:淘宝在国外 编辑:程序博客网 时间:2024/05/22 06:36

直方图在图形处理中很常用,直方图可以统计图像的像素特征分布,用于修改图像显示,修改图像内容,通过比较不同图片的直方图可以识别和跟踪特殊纹理的物体和图像,下面先学习怎么计算图像的直方图。

      opencv2提供calchist函数可以方便的计算直方图。

      calchist函数头文件 #include <opencv2/imgproc/imgproc.hpp>

      calchist函数定义:

[cpp] view plain copy
  1. //! computes the joint dense histogram for a set of images.  
  2. CV_EXPORTS void calcHist( const Mat* images, int nimages,  
  3.                           const int* channels, InputArray mask,  
  4.                           OutputArray hist, int dims, const int* histSize,  
  5.                           const float** ranges, bool uniform=truebool accumulate=false );  
  6.   
  7. //! computes the joint sparse histogram for a set of images.  
  8. CV_EXPORTS void calcHist( const Mat* images, int nimages,  
  9.                           const int* channels, InputArray mask,  
  10.                           SparseMat& hist, int dims,  
  11.                           const int* histSize, const float** ranges,  
  12.                           bool uniform=truebool accumulate=false );  
  13.   
  14. CV_EXPORTS_W void calcHist( InputArrayOfArrays images,  
  15.                             const vector<int>& channels,  
  16.                             InputArray mask, OutputArray hist,  
  17.                             const vector<int>& histSize,  
  18.                             const vector<float>& ranges,  
  19.                             bool accumulate=false );  
      举例说明函数应用:

[cpp] view plain copy
  1. Histogram1D::Histogram1D(){  
  2.     histSize[0] = 256;   
  3.     hranges[0] = 0.0;  
  4.     hranges[1] = 255.0;  
  5.     ranges[0] = hranges;  
  6.     channels[0] = 0;  
  7. }  
  8.   
  9. cv::MatND Histogram1D::getHistogram(const cv::Mat &image){  
  10.     cv::MatND hist;  
  11.     cv::calcHist(&image,   //source image  
  12.              1,        //histogram from 1 image only  
  13.              channels, //the channel used  
  14.              cv::Mat(),//no mask is uesd  
  15.              hist,     //the resulting histogram  
  16.              1,        //it is a 1D histogram  
  17.              histSize, //number of bins  
  18.              ranges    //pixel value range  
  19.                 );//直方图函数  
  20.     return hist;  
  21. }  

       函数参数介绍:

const Mat* images      //源图像组

int nimages       (Number of source arrays)   //源图像组图像个数

const int* channels   (List of the dims channels used to compute the histogram.)   //图像信道

InputArray mask   ( Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size as arrays[i].  The non-zero mask elements mark the array elements counted in the histogram.)
                          //可选的掩码,如果不为空,则必须是8-bit数组,而且大小和原图像相同,非零位置为要计算的直方  图区域

OutputArray hist   (Output histogram, which is a dense or sparse dims -dimensional array.)
                       //输出直方图数组,稠密或者稀疏,dims维的数组

int dims    ( Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS)
                        //处理直方图的维数正数,最大32维,CV_MAX_DIMS是32.

const int* histSize   ( Array of histogram sizes in each dimension.)
                      //每一维的直方图的尺寸大小

const float** ranges    (Array of the dims arrays of the histogram bin boundaries in each dimension. When the histogram is uniform ( uniform =true),   then for each dimension i it is enough to specify the  lower (inclusive) boundary of the 0-th histogram bin and the upper(exclusive)  boundary for  the last histogram bin histSize[i]-1. That is, in case of a uniform histogram each of ranges[i] is  an array of 2 elements.   When the histogram is not uniform ( uniform=false ), then each of  ranges[i] contains histSize[i]+1 elements:.  The array elements, that are not between  and,are not counted in the histogram.)
                                  //直方图每一维的数据大小范围

 下面是计算1维图像的直方图:

[cpp] view plain copy
  1. cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image){  
  2.     //compute histogram first  
  3.     cv::MatND hist = getHistogram(image);  
  4.     //get min and max bin values  
  5.     double maxVal = 0;  
  6.     double minVal = 0;  
  7.     cv::minMaxLoc(hist,&minVal,&maxVal,0,0);  
  8.     //Image on which to display histogram  
  9.     cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));  
  10.     //set highest point at 90% of nbins   
  11.     int hpt = static_cast<int>(0.9*histSize[0]);  
  12.     //Draw a vertical line for each bin   
  13.     for (int h =0;h<histSize[0];h++)  
  14.     {  
  15.         float binVal = hist.at<float>(h);  
  16.         int intensity = static_cast<int>(binVal*hpt/maxVal);  
  17.         cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar::all(0));  
  18.     }  
  19.     return histImg;  
  20. }  
             源图像:

                    histogram:

 计算H-S直方图分布:

[cpp] view plain copy
  1. /********************************************* 
  2.              内容:计算H-S 直方图分布       
  3.              时间:2013 5.27 
  4.          作者:恋上蛋炒面       
  5. *********************************************/  
  6. #include <opencv2/core/core.hpp>  
  7. #include <opencv2/highgui/highgui.hpp>  
  8. #include <opencv2/imgproc/imgproc.hpp>  
  9. using namespace cv;  
  10.   
  11. void main()  
  12. {  
  13.     Mat source = imread("baboon.jpg");  
  14.     namedWindow("Source");  
  15.     imshow("Source",source);  
  16.     Mat hsv;  
  17.     cvtColor(source,hsv,CV_BGR2HSV);  
  18.     //Quantize the hue to 60 levels  
  19.     //and the saturation to 64 levels  
  20.     int hbins = 60,sbins = 64;  
  21.     int histSize[] = {hbins,sbins};  
  22.     //hue varies from 0 to 179  
  23.     float hranges[] = {0,180};  
  24.     //saturation varies from 0 to 255  
  25.     float sranges[] = {0,255};  
  26.     const float *ranges[] = {hranges,sranges};  
  27.     //two channels 0th,1th  
  28.     int channels[] = {0,1};  
  29.     MatND hist;  
  30.     //compute h-s histogram  
  31.     calcHist(&hsv,1,channels,Mat(),hist,2,histSize,ranges);  
  32.     //get the max value  
  33.     double maxVal = .0;  
  34.     minMaxLoc(hist,0,&maxVal,0,0);  
  35.     int scale = 8;  
  36.     //show the histogram on the image  
  37.     Mat histImg = Mat::zeros(sbins*scale,hbins*scale,CV_8UC3);  
  38.     for (int h = 0;h < hbins;h++)  
  39.     {  
  40.         for (int s = 0;s<sbins;s++)  
  41.         {  
  42.             float binVal = hist.at<float>(h,s);  
  43.             int intensity = cvRound(binVal*0.9*255/maxVal);  
  44.             rectangle(histImg,Point(h*scale,s*scale),Point((h+1)*scale-1,(s+1)*scale-1),Scalar::all(intensity),CV_FILLED);  
  45.         }  
  46.     }  
  47.   
  48.     namedWindow("H-S Histogram");  
  49.     imshow("H-S Histogram",histImg);  
  50.     imwrite("hshistogram.jpg",histImg);  
  51.     waitKey(0);  
  52. }  

       源图像:


h-s histogram:


   RGB直方图:

[cpp] view plain copy
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3. #include <opencv2/imgproc/imgproc.hpp>  
  4.   
  5. #include <fstream>  
  6.   
  7. using namespace cv;  
  8. using namespace std;  
  9.   
  10. void main()  
  11. {  
  12.     //Mat source = imread("red.jpg");  
  13.     Mat source = imread("baboon.jpg"); //读取图片  
  14.     //Mat source(300,300,CV_8UC3,Scalar(1,1,244));  
  15.     //imwrite("red.jpg",source);  
  16.     namedWindow("Source");//窗口显示图片  
  17.     imshow("Source",source);  
  18.     //初始化calcHist函数的参数  
  19.     int channels_r[1],channels_g[1],channels_b[1],histSize[1],range;  
  20.     float hranges[2];  
  21.     const float *ranges[1];  
  22.     histSize[0] = 256;  
  23.     hranges[0] = 0.0;  
  24.     hranges[1] = 255.0;  
  25.     ranges[0] = hranges;  
  26.     channels_b[0] = 0;  
  27.     channels_g[0] = 1;  
  28.     channels_r[0] = 2;  
  29.     MatND hist_r,hist_g,hist_b;  
  30.   
  31.     double max_val_r,max_val_g,max_val_b;  
  32.     Mat histImage(histSize[0],3*histSize[0],CV_8UC3); //定义一个显示直方图的图片,长256*3 高256  
  33.     //R  
  34.     calcHist(&source,1,channels_r,Mat(),hist_r,1,histSize,ranges);//分别计算R,G,B的直方图分布  
  35.     minMaxLoc(hist_r,0,&max_val_r,0,0);//计算直方图中统计最大值  
  36.     //G  
  37.     calcHist(&source,1,channels_g,Mat(),hist_g,1,histSize,ranges);  
  38.     minMaxLoc(hist_g,0,&max_val_g,0,0);  
  39.     //B  
  40.     calcHist(&source,1,channels_b,Mat(),hist_b,1,histSize,ranges);  
  41.     minMaxLoc(hist_b,0,&max_val_b,0,0);  
  42.   
  43.     //将r,g,b的最大统计值,以及像素点从0-255的统计值写入txt中  
  44.     ofstream outfile1("d:\\r.txt");  
  45.     ofstream outfile2("d:\\g.txt");  
  46.     ofstream outfile3("d:\\b.txt");  
  47.   
  48.     //在txt中写入最大统计值  
  49.     outfile1<<"max_val_r = "<<max_val_r<<endl;  
  50.     outfile2<<"max_val_g = "<<max_val_g<<endl;  
  51.     outfile3<<"max_val_b = "<<max_val_b<<endl;  
  52.   
  53.     for (int i =0;i<histSize[0];i++)  
  54.     {         
  55.         //R,G,B= i的统计值  
  56.         float binVal_r = hist_r.at<float>(i);  
  57.         float binVal_g = hist_g.at<float>(i);  
  58.         float binVal_b = hist_b.at<float>(i);  
  59.         //统一R,G,B统计值的大小,以高度的90%封顶  
  60.         int intensity_r = static_cast<int>(0.9*histSize[0]*binVal_r/max_val_r);  
  61.         outfile1<<i<<" "<<binVal_r<<" "<<intensity_r<<endl;  
  62.         int intensity_g = static_cast<int>(0.9*histSize[0]*binVal_g/max_val_g);  
  63.         outfile2<<i<<" "<<binVal_g<<" "<<intensity_g<<endl;  
  64.         int intensity_b = static_cast<int>(0.9*histSize[0]*binVal_b/max_val_b);  
  65.         outfile3<<i<<" "<<binVal_b<<" "<<intensity_b<<endl;  
  66.         //画出R,G,B的直方图直线  
  67.         line(histImage,Point(i,histImage.rows),Point(i,histImage.rows-intensity_r),Scalar(0,0,255));  
  68.         line(histImage,Point(i+histSize[0],histImage.rows),Point(i+histSize[0],histImage.rows-intensity_g),Scalar(0,255,0));  
  69.         line(histImage,Point(i+histSize[0]*2,histImage.rows),Point(i+histSize[0]*2,histImage.rows-intensity_b),Scalar(255,0,0));  
  70.     }  
  71.     namedWindow("RGB Histogram");  
  72.     imshow("RGB Histogram",histImage);  
  73.     imwrite("RGB_Histogram.jpg",histImage);  
  74.     waitKey(0);  
  75. }  

                     源图像:如上图

                     程序运行结果:

转自 http://blog.csdn.net/skeeee/article/details/8979811

0 0
原创粉丝点击