当前位置:   article > 正文

opencv 图像直方图详解_opencv 直方图

opencv 直方图

理论基础

直方图
直方图是数值数据分布的精确图形表示。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。
图像直方图
图像直方图统计的可以是对描述图像有用的任何特征,如灰度值,梯度等。
直方图是图像的一个统计特征,它具有旋转、缩放、平移不变性,被应用于灰度图像的阈值分割,对比度调整,颜色匹配等等。下面以灰度图像灰度直方图说明统计的原理:
在这里插入图片描述
考虑以上灰度值图像,我们如何统计这些数据呢?我们知道灰度值在0 - 255范围之间总共 256 个值,可以将我们的范围划分为子部分(称为bins),例如:
在这里插入图片描述
计算每个bini范围内像素的数量。得到下图(x轴表示bin,y轴表示每个箱子中的像素数)。
在这里插入图片描述
直方图重要概念:
dim:希望收集数据的参数数量。在上面例子中,dims = 1是因为我们只计算每个像素(在灰度图像中)的强度值。
bin:在上面例子的示例中,bins = 16
range:要测量的值的限制。在本例中:range = [0,255]

一、opencv 函数支持calcHist()

计算一组数组的直方图。函数原型,三个重载函数:

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

/** @overload

this variant uses %SparseMat for output
*/
CV_EXPORTS 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 );

/** @overload */
CV_EXPORTS_W void calcHist( InputArrayOfArrays images,
                            const std::vector<int>& channels,
                            InputArray mask, OutputArray hist,
                            const std::vector<int>& histSize,
                            const std::vector<float>& ranges,
                            bool accumulate = false );

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

参数说明:
images:源数组。它们都应该具有相同的深度,CV_8U, CV_16U或CV_32F,以及相同的大小。它们中的每一个都可以有任意数量的通道。
nimages:源图像个数。
channels:要测量的通道。
mask:源数组上使用的掩码(0表示要忽略的像素)。如果没有定义,则不使用
hist:输出直方图数组。
dims:直方图维度,必须是正的,不大于CV_MAX_DIMS(在当前OpenCV版本中等于32)。
histSize:每个维度bind的数量
ranges:每个维度要测量的值的范围
uniform:表示直方图是否均匀的标志(见上)。
accumulate:积累标志。如果设置了,则分配直方图时,一开始不清除。该特性使您能够从多个数组集合中计算出一个直方图,或者及时更新直方图。

代码示例

    cv::Mat image = cv::imread("D:\\QtProject\\Opencv_Example\\Hist\\Hist.png", cv::IMREAD_GRAYSCALE);
    if (image.empty()) {
      cout << "Cannot load image" << endl;
      return;
    }
    imshow("image",image);
    const int bins[1] = { 256 };
    float hranges[2] = { 0,255 };
    const float* ranges[1] = { hranges };

    Mat hist;
    // 计算直方图
    calcHist(&image, 1, 0, Mat(), hist, 1, bins, ranges);

    // 显示直方图
    int hist_w = 500;
    int hist_h = 600;
    int bin_w = cvRound((double)hist_w / bins[0]);  //两个灰度级之间的距离
    Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3); //直方图画布
    // 归一化直方图数据
    normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); //将数据规皈依到0和hist_h之间
    // 绘制直方图曲线
    for (int i = 1; i < bins[0]; 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(0, 255, 0), 2, 8, 0);
    }
    // 显示直方图
    namedWindow("Histogram", WINDOW_AUTOSIZE);
    imshow("Histogram", histImage);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

运行效果:
原图:
在这里插入图片描述
直方图:
在这里插入图片描述
参考文章:https://docs.opencv.org/4.x/d8/dbc/tutorial_histogram_calculation.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/141047
推荐阅读
相关标签
  

闽ICP备14008679号