OpenCV 直方图统计函数 cv::calcHist算是彻底弄明白了 您所在的位置:网站首页 像素值的范围是什么 OpenCV 直方图统计函数 cv::calcHist算是彻底弄明白了

OpenCV 直方图统计函数 cv::calcHist算是彻底弄明白了

2024-06-22 00:32| 来源: 网络整理| 查看: 265

参数说明 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 ); images 图像数组。每个图像的大小要一致,depth要一致,即数据类型要一致,但通道数可以不一致。nimages 图像数组的大小,即images数组的大小channels 参与计算的各个通道的索引。由于各图像的通道数并不一定一致,并且此函数也不强制要求所有通道都参与计算,因此此参数用于指定要参与计算的图像的通道索引。索引值包含了图像标识,以及图像的通道标识。具体方法为: 第一个图像的索引标识为 [0,  images[0].channels()),  第二个图像的索引标识为 [mages[0].channels(),  mages[0].channels()+mages[1].channels()) 之后以此类推。 例如: 图像mages[0]有三个通道,其通道索引为{0, 1, 2}; 图像mages[1] 有两个通道,其通过索引为 {3, 4}; 图像mages[2] 有三个通道,其通过索引为 {5, 6, 7}mask 此函数支持对图像中指定区域进行直方图统计hist 直方图统计结果dims 直方图维度。使用最多的也就是1维、2维,更高维应该很少吧。本文后续再详细说明。histSize 指定各个通道的的直方图中分类数。此函数的设计是,多个像素取值可以划分为同个分类,例如:像素灰度值取值范围是[0, 255],但不一定要分成256类,可以为了8类,就可以通过histSize 这个参数指定。ranges 指定各个通道的像素灰度值的取值范围。也就是说,此函数的设计并不要求各个通道的像素灰度值取值范围一致。例如:可以第一个通道取值是[0, 255], 第二个通道取值是[0, 127]。 此外,此参数地用于与uniform的取值有关。 uniform取值为true时,表示将像素取值平均分配为 histSize[i]个区域(此处的i表示,参与计算的第i个通道),此时,ranges[i]数组的大小通道是2,即ranges[i][0] 表示像素值的最小值,ranges[i][1]表示像素取值的最大值。 uniform取值为false时,表示不平均分配区间。此时,此函数就不知道如何划分区间了,就需要调用者指定。此时,ranges[i]数组的大小为区间个数加1,即histSize[i]+1。 一维颜色直方图

如果要统计一个RGB图像,三个通道的各自的直方图,需要将dims设置为1,并调用三次calcHist函数。

{ READ_IMG_DEF_ERR_RET(img, "img1.jpg"); cv::imshow("原始图像", img); int channels[1] = { 0 }; int histSize[1] = { 256 }; float range[2] = { 0, 256 }; const float* ranges[1] = { range}; // 指定每个通道的取值范围 // 计算B通道的颜色直方图 cv::Mat bHist; cv::calcHist(&img, 1, channels, cv::Mat(), bHist, 1, histSize, ranges); PRINT_IMG_INFO(bHist); // 计算G通道的颜色直方图 cv::Mat gHist; cv::calcHist(&img, 1, channels, cv::Mat(), gHist, 1, histSize, ranges); PRINT_IMG_INFO(gHist); // 计算R通道的颜色直方图 cv::Mat rHist; cv::calcHist(&img, 1, channels, cv::Mat(), rHist, 1, histSize, ranges); PRINT_IMG_INFO(rHist); cv::Mat bHistImg = ImgTools->buildHistImg(bHist, 600, 600, cv::Scalar(255, 0, 0)); cv::imshow("颜色直方图 B", bHistImg); cv::Mat gHistImg = ImgTools->buildHistImg(gHist, 600, 600, cv::Scalar(0, 255, 0)); cv::imshow("颜色直方图 G", gHistImg); cv::Mat rHistImg = ImgTools->buildHistImg(rHist, 600, 600, cv::Scalar(0, 0, 255)); cv::imshow("颜色直方图 R", rHistImg); cv::waitKey(0); } 二维颜色直方图

此时需要将dims参数设置为2。

{ cv::Mat imgs[2]; imgs[0] = (cv::Mat_(2, 4) dumpImg(imgs[1], "imags[1]: "); cv::Mat img; cv::merge(imgs, sizeof(imgs) / sizeof(imgs[0]), img); ImgTools->dumpImg(img, "imag: "); int channels[3] = { 0, 1 }; int histSize[3] = { 8, 8 }; float rRange[2] = { 0, 8 }; float gRange[2] = { 8, 16 }; const float* ranges[2] = { rRange, gRange}; // 指定每个通道的取值范围 cv::Mat hist; cv::calcHist(&img, 1, channels, cv::Mat(), hist, 2, histSize, ranges); ImgTools->dumpImg(hist, "hist info:"); }

运行结果如下图所示:

 在代码中,计算两个通道,通过参数histSize指定,每个通道都分成8个分区,因此可能有64种组合结果,因此二维直方图的大小为8*8的矩阵。

在图像中(3,10)这个组合的数据只有一个,对应的分区编号是(3,2),因此二维直方图中(3,2)位置的数据值为1,即上图中绿色标记的位置。 在图像中 (3, 11)这个组合的数据有两个, (3, 11)对应的分区编号是(3,3),因此上图中的红色标记的位置的统计值为2



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有