当前位置:网站首页 > 创业 > 正文

OpenCV:calcHist计算图像直方图

0 张子豪 张子豪 2025-10-12 04:07 1

绪:

直方图可展示图像中的像素分布,是用以暗示数字图像中亮度分布的直方图,

标绘了图像中每个亮度值的像素数。

可以借助不雅察该直方图领会需要若何调整亮度分布。

本文本家儿要介绍opencv中绘制直方图的函数calHist的格局和用法;

东西/原料

  • OpenCV 2410

方式/步调

  1. 1

    calcHist三种函数原型:

    opencv中自带了求算图像直方图的函数calhist(),

    函数原型如下:

    ①void calcHist( const Mat* images,

                              int nimages, 

                              const int* channels,

                              InputArray mask,

                             OutputArray hist,

                             int dims,

                             const int* histSize, 

                            const float** ranges,

                            bool uniform=true,

                            bool accumulate=false ); 

    ②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 ); 

    ③void calcHist( InputArrayOfArrays images, 

                             const vector<int>& channels, 

                             InputArray mask,

                            OutputArray hist, 

                            const vector<int>& histSize, 

                            const vector<float>& ranges, 

                            bool accumulate=false );  

  2. 2

    calcHist参数详解:

    以第一个函数原型为例:

    ①const Mat* images:为输入图像的指针;

    ②int nimages:要计较直方图的图像的个数。此函数可觉得多图像求直方图,我们凡是环境下都只感化于单一图像,所以凡是nimages=1。

    ③const int* channels:图像的通道是一个数组,若是是灰度图像则channels[1]={0};若是是彩色图像则channels[3]={0,1,2};若是只是求彩色图像第2个通道的直方图则channels[1]={1};

    ④IuputArray mask:掩膜,仅对指心猿意马元素操作,默认环境设置为一个空图像,即:Mat()。

    ⑤OutArray hist:计较获得的直方图

    ⑥int dims:获得的直方图的维数,灰度图像为1维,彩色图像为3维

    ⑦const int* histSize:直方图横坐标的区间数。若是是10,则它会横坐标分为10份,然后统计每个区间的像素点总和

    ⑧const float** ranges:这是一个二维数组,用来指出每个区间的规模

    ⑨uniform参数表白直方图是否等距,

    ⑩accumulate与多图像下直方图的显示与存储有关;

  3. 3

    注重的处所:

    关于calHist计较直方图的成果hist,

    hist的成果为统计的灰度级0,1,…,255的数目;

    暗示一维或三维的矩阵;

    对于直方图成果矩阵,拜候形式为:

    cout<<hist.at<float>(i)<<endl;

  4. 4

    灰度图的直方图绘制:

    #include <opencv2\opencv.hpp>

    #include <opencv2\highgui\highgui.hpp>

    #include <opencv2\features2d\features2d.hpp>

    #include <opencv2\core\core.hpp>

    using namespace std; 

    using namespace cv; 

    int main() 

           Mat srcImage = imread("mask.jpg"); 

           imshow("【原图】", 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); 

           //calcHist 函数挪用竣事后,

           //dstHist变量中将储存了直方图的信息;

           //用dstHist的模版函数 at<Type>(i)获得第i个柱条的值 

           //at<Type>(i, j)获得第i个而且第j个柱条的值   

           Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3); 

           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(255, 0, 0)); 

           }

           imshow("【直方图】", drawImage); 

           waitKey(0); 

           return 0;  

    }     

  5. 5

    彩色直方图的绘制:

    int main() 

           Mat srcImage = imread("mask.jpg"); 

           imshow("【原图】", srcImage); 

           int channels = 0; 

           MatND dstHist;  

           int histSize =  256 ;

           float midRanges[] = { 0, 256 }; 

           const float *ranges[] = { midRanges }; 

           calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, &histSize, ranges, true, false); 

           //绘制蓝色通道

           Mat b_drawImage = Mat::zeros(Size(256, 256), CV_8UC3);  

           double g_dHistMaxValue = 0; 

           minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0); 

           for (int i = 0; i < histSize; i++) 

           { 

                  int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue); 

                  rectangle(b_drawImage,

                         Point(i * 8, b_drawImage.rows - 1),

                         Point(i * 8 + 256 / histSize, b_drawImage.rows - 1 - value) 

                         ,Scalar(255, 0, 0), -1); 

           } 

           imshow("【蓝色通道的直方图】", b_drawImage); 

           //绘制绿色通道 

           channels = 1; 

           calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, &histSize, ranges, true, false); 

           Mat g_drawImage = Mat::zeros(Size(256, 256), CV_8UC3); 

           minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0); 

           for (int i = 0; i < histSize; i++) 

           { 

                  int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue); 

                  rectangle(g_drawImage,

                         Point(i * 8, g_drawImage.rows - 1),

                         Point(i * 8 + 256 / histSize, g_drawImage.rows - 1 - value),

                         Scalar(0, 255, 0), -1); 

           } 

           imshow("【绿色通道的直方图】", g_drawImage); 

           //绘制红色通道 

           channels = 2; 

           calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, &histSize, ranges, true, false); 

           Mat r_drawImage = Mat::zeros(Size(256, 256), CV_8UC3); 

           minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0); 

           for (int i = 0; i < histSize; i++) 

           { 

                  int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue); 

                  rectangle(r_drawImage,

                         Point(i * 8, r_drawImage.rows - 1),

                         Point(i * 8 + 256 / histSize, r_drawImage.rows - 1 - value),

                         Scalar(0, 0, 255), -1); 

           } 

           imshow("【红色通道的直方图】", r_drawImage); 

           waitKey(0); 

           return 0; 

    }  

  6. 6

    【注】:

    calhist()函数求得的直方图返回值是一个一维或三维等的矩阵;不是二维;

    经由过程hist.at<float>(i)格局拜候;

注重事项

  • hist.at(i):拜候的格局
  • 彩色直方图的生当作;

来源:百闻(微信/QQ号:9397569),转载请保留出处和链接!


本文链接:https://www.ibaiwen.com/web/236157.html

张子豪

张子豪

TA很懒,啥都没写...

@百闻娱乐 本站部分内容转自互联网,若有侵权等问题请及时与本站联系,我们将在第一时间删除处理。 | 粤ICP备2024343649号 | (地图