Opencv(C++)学习之cv::calcHist 任意bin数量进行直方图计算

**背景:**当前网上常见的直方图使用方法都是默认使用256的范围,而对于使用特定范围的直方图方法讲的不够清楚。仔细研究后总结如下:

1、常见使用方法,直接对灰度图按256个Bin进行计算。

Mat mHistUn;
int channels[1] = {
    0 };
{
   
    bool uniform = true;//使用标准方法-也就是每个bin长度为1
    int histSize[1] = {
    256 };
    float range[2] = {
    0, 255 };
    const float* ranges[] = {
    range }; // 指定单个bin的取值范围

    cv::calcHist(&src, 1, channels, cv::Mat(), mHistUn, 1, histSize, ranges, uniform);
}

2、使用128个Bin进行计算

Mat mHist;
int channels[1] = {
    0 };
{
   
    bool uniform = false;
    int histSize[1] = {
    128 };
    float range[129] = {
    0 };
    for (size_t i = 0, j = 0; i < 129; i++, j += 2)
        range[i] = j;
    const float* ranges[] = {
    range }; // 指定单个bin的取值范围

    cv::calcHist(&src, 1, channels, cv::Mat(), mHist, 1, histSize, ranges, uniform);
}

在该方法中,channels为0 ,表示单通道。先将uniform 标志位置为false,表示单个bin不再使用默认的距离1。
再构建每个bin的取值范围ranges,这里bin的宽度按2进行配置 ,那么所有的bin就是[0,2],[2,4],[4,6]…[254,255],总共128个bin。
其中需要注意的是,128个bin,但ranges的大小是129.这和opencv对这块的数据处理相关。

3、观察效果

void showCvHist(Mat srchist, int histSize)
{
   
    int hist_w = 511;
    int hist_h = 400;
    int bin_w = cvRound((double)hist_w / histSize);
    Mat histImage(hist_h, hist_w, CV_8UC1, Scalar(0, 0, 0));
    Mat hist = srchist.clone();
    normalize(hist, hist, 0, hist_h, NORM_MINMAX, -1, Mat());

    for (int i = 1; i < histSize; 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("tt", histImage);
    cv::waitKey(0);
}

使用该函数对结果进行显示
256方法:
256bin的直方图
128的方法
128bin的直方图

可以看到,直方图的趋势基本类似。我们再看下直方图统计的具体数据。可以看到,在128bin方法中,每个数据正好对应256方法中2个数据之和。说明bin宽度为2正好生效。
256bin与128bin的数据对比1
4、一点统计的疑问:数据的最尾端,[254,255]合并成[127]时,数据存在3000的差异,不知从何引入的。
有知道的朋友可以帮忙看下

256bin与128bin的数据对比2

相关推荐

  1. opencv直方图

    2024-01-03 10:56:03       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-03 10:56:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-03 10:56:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-03 10:56:03       82 阅读
  4. Python语言-面向对象

    2024-01-03 10:56:03       91 阅读

热门阅读

  1. HBASE基础

    2024-01-03 10:56:03       59 阅读
  2. css视觉格式化模型

    2024-01-03 10:56:03       59 阅读
  3. 对html骨架的详细解释

    2024-01-03 10:56:03       60 阅读
  4. 【WPF.NET开发】如何创建自定义路由事件

    2024-01-03 10:56:03       70 阅读
  5. 微信养号指南:提高账号权重

    2024-01-03 10:56:03       67 阅读
  6. LDD学习笔记 -- 用户空间 & 内核空间

    2024-01-03 10:56:03       65 阅读
  7. 微信小程序 wx.request二次封装

    2024-01-03 10:56:03       65 阅读
  8. 卸载云服务器上的 MySQL 数据库

    2024-01-03 10:56:03       54 阅读
  9. C++ 拷贝构造函数

    2024-01-03 10:56:03       56 阅读
  10. User mkcert 生成本地证书的步骤

    2024-01-03 10:56:03       64 阅读