您的位置:首页 > 运维架构

[OpenCV基础] 直方图之calcHist使用

2014-08-07 19:03 288 查看
原文参考自:http://blog.csdn.net/sydnash/article/details/7451039
以及:http://blog.csdn.net/ljbkiss/article/details/7412787
opencv提供了calcHist函数来计算图像直方图。
         其中C++的函数原型如下: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 );
          void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, SparseMat&

hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=

false );
         参数解释:
        arrays。输入的图像的指针,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)。同时每一副图像可以有多个channes。
        narrays。输入的图像的个数。
        channels。用来计算直方图的通道维数数组,第一个数组的通道由0到arrays[0].channels()-1列出,第二个数组的通道从arrays[0].channels()到arrays[0].channels()+arrays[1].channels()-1以此类推;channels与arrays中的图像的对应关系,将arrays中的图像从第0幅开始按照通道摊开排列起来,然后channels中的指定的用于计算直方图的就是这些摊开的通道;假设有arrays中只有一幅三通道的图像image,那么narrays应该为1,如果是想计算3维直方图【最大也只能是3维的】,想将image的通道2作为第一维,通道0作为第二维,通道1作为第三维,则可以将channels设置为channesl={2,0,1};这样calcHist函数计算时就按照这个顺序来统计直方图。如果channels参数为0,则narrays和dims必须相等,否则弹出assert,此时计算直方图的时候取数组中每幅图像的第0通道。channels不为0时narrays可以和dims不相等,只要保证arrays中至少有channels指定的通道就可以。

        mask。 可选的掩膜,如果该矩阵不是空的,则必须是8位(CV_8U)的并且与arrays[i]的大小相等,掩膜的非零值标记需要在直方图中统计的数组元素;
        hist。输出计算出的直方图,是一个稠密或者稀疏的dims维的数组;
        dims。计算出来的直方图的维数。必须为正,并且不大于CV_MAX_DIMS(当前的OpenCV版本中为32,即最大可以统计32维的直方图);(统计的变量个数)
        histSize。 用于指出直方图数组每一维的大小的数组,即指出每一维的bin的个数的数组;(每维分成多少份),在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。
        ranges。用来进行统计的范围。比如
         float rang1[] = {0, 20};
        float rang2[] = {30, 40};
        const float *rangs[] = {rang1, rang2};那么就是对0,20和30,40范围的值进行统计。
        用于指出直方图每一维的每个bin(份)的上下界范围数组的数组,当直方图是均匀的(uniform =true)时,对每一维i指定直方图的第0个bin的下界(包含)L0和最 后一个即第histSize[i]-1个bin的上界(不包含))U_histSize[i]-1,也就是说对均匀直方图来说,每一个ranges[i]都是一个两个元素的数组【指出该维的上下界】。当直方图不是均匀的时,每一个ranges[i]数组都包含histSize[i]+1个元素:L0,U0=L1,U1=L1,...,U_histSize[i]-2
= L_histSize[i]-1,U_histSize[i]-1.不在L0到U_histSize[i]-1之间的数组元素将不会统计进直方图中;
       uniform。每一个竖条的宽度是否相等,或说每个bin统计的是否是相同数量的灰度级。
       accumulate。 是否累加。如果为true,在下次计算的时候不会首先清空hist。

<span style="font-size:12px;">    //生成一幅单通道图像。
cv::Mat image(imageHeight, imageWidth, CV_8U, imageAddress);

cv::MatND histogram;
//256个,范围是0,255.
 const int histSize = 256;
float range[] = {0, 255};
const float *ranges[] = {range};
const int channels = 0;

cv::calcHist(image, 1, &channels, cv::Mat(), histogram, 1, &histSize, &ranges[0], true, false);
int row = histogram.rows;
int col = histogram.cols;

float *h = (float*)histogram.data;
double hh[256];
if (h) {
for (int i = 0; i < 256; ++i) {
hh[i] = h[i];
}
}
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OpenCV基础