今天做了一下opencv1的直方图实验,结果被坑了一上午。
直方图的含义十分简单,就是统计各个像素值的分布情况,因此我们的操作对象应该是一个单通道图,当然多通道图也可以,这样做出来的就是多维直方图,不过就一般应用而言,还是一维直方图用得比较多。
opencv中集成了计算直方图的函数,说实话,这个函数的传参有点过于复杂了,不过如果有个例子比照着写还是比较简单的。另外,要注意的是,如果要在函数中计算直方图,传参时务必要使用指针或者引用,只有这样,计算出的直方图才能在函数外部访问到,否则会一直出现错误。
/* 本函数用于计算直方图,注意传入参数必须为hist的引用 输入为单通道图,hist矩阵和bins的数目 */ void myCal_Hist(Mat &Gray_img,Mat &hist,int binsNum) { int hist_size[] = {binsNum}; float range[] = { 0, 256 }; const float* ranges[] = { range}; int channels[] = {0}; //计算直方图 calcHist( &Gray_img, 1, channels, Mat(), // do not use mask hist, 1, hist_size, ranges, true, // the histogram is uniform false ); } /* 绘制hist图像 */ void showHist(Mat &hist,int binsNum) { int hist_w = 512; int hist_h = 400; int bin_w = cvRound( (double) hist_w/binsNum ); Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); /// Normalize the result to [ 0, histImage.rows ] normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); for(int i = 1;i < binsNum;i++) { line( histImage, Point( bin_w*(i-1), hist_h - cvRound(hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 ); } imshow("calcHist Demo", histImage ); }