Opencv(十六)绘制图像直方图

图像直方图是图像处理中非常重要的像素统计结果,图像直方图不再表征任何的图像纹理信息,而是对图像像素的统计。由于同一物体无论是旋转还是平移在图像中都具有相同的灰度值,因此直方图具有平移不变性、放缩不变性等优点,因此可以用来查看图像整体的变化形式。

图像直方图简单来说就是统计图像中每个灰度值的个数,之后将图像灰度值作为横轴,以灰度值个数或者灰度值所占比率作为纵轴绘制的统计图。通过直方图可以看出图像中哪些灰度值数目较多,哪些较少。

1、图像直方图的统计函数calcHist()

void cv::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:待统计直方图的图像数组,数组中所有的图像应具有相同的尺寸和数据类型,并且数据类型只能是CV_8U、CV_16U和CV_32F三种中的一种,但是不同图像的通道数可以不同

nimages:输入的图像数量

channels:需要统计的通道索引数组,第一个图像的通道索引从0到images[0].channels()-1,第二个图像通道索引从images[0].channels()到images[0].channels()+ images[1].channels()-1,以此类推

mask:可选的操作掩码,如果是空矩阵则表示图像中所有位置的像素都计入直方图中,如果矩阵不为空,则必须与输入图像尺寸相同且数据类型为CV_8U

hist:输出的统计直方图结果,是一个dims维度的数组

dims:需要计算直方图的维度,必须是整数,并且不能大于CV_MAX_DIMS,在OpenCV 4.0和OpenCV 4.1版本中为32

histSize:存放每个维度直方图的数组的尺寸

ranges:每个图像通道中灰度值的取值范围

uniform:直方图是否均匀的标志符,默认状态下为均匀(true)

accumulate:是否累积统计直方图的标志,如果累积(true),则统计新图像的直方图时之前图像的统计结果不会被清除,该同能主要用于统计多个图像整体的直方图

2、代码

  #include <opencv2\opencv.hpp>
  #include <iostream>
  
  using namespace cv;
  using namespace std;
  
  int main()
 {
    Mat img = imread("apple.jpg");
    if (img.empty())
    {
      cout << "请确认图像文件名称是否正确" << endl;
      return -1;
    }
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    //设置提取直方图的相关变量
    Mat hist; //用于存放直方图计算结果
    const int channels[1] = { 0 }; //通道索引
    float inRanges[2] = { 0,255 };
    const float* ranges[1] = { inRanges }; //像素灰度值范围
    const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值
    calcHist(&img, 1, channels, Mat(), hist, 1, bins, ranges); //计算图像直方图
    //准备绘制直方图
    int hist_w = 512;
    int hist_h = 400;
    int width = 2;
    Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
    for (int i = 1; i <= hist.rows; i++)
    {
    rectangle(histImage, Point(width*(i - 1), hist_h - 1),
        Point(width*i - 1, hist_h - cvRound(hist.at<float>(i - 1) / 20)),
        Scalar(255, 255, 255), -1);
    }
    namedWindow("histImage", WINDOW_AUTOSIZE);
    imshow("histImage", histImage);
    imshow("gray", gray);
    waitKey(0);
    return 0;
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV提供了一个函数cv::calcHist()来计算图像直方图,在绘制之前需要将图像转换为灰度图像。下面是一个简单的示例代码,用于绘制灰度图像直方图: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 读取图像 Mat image = imread("example.jpg", IMREAD_GRAYSCALE); // 定义直方图参数 int histSize = 256; // 直方图中条目的数量 float range[] = { 0, 256 }; // 像素值范围 const float* histRange = { range }; bool uniform = true, accumulate = false; // 计算直方图 Mat hist; calcHist(&image, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate); // 绘制直方图 int hist_w = 512, hist_h = 400; int bin_w = cvRound((double)hist_w / histSize); Mat histImage(hist_h, hist_w, CV_8UC1, Scalar(0)); normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); for (int i = 1; i < histSize; i++) { line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(hist.at<float>(i - 1))), Point((i)*bin_w, hist_h - cvRound(hist.at<float>(i))), Scalar(255), 2, LINE_AA); } // 显示绘制直方图 namedWindow("Histogram", WINDOW_AUTOSIZE); imshow("Histogram", histImage); waitKey(0); return 0; } ``` 在这个示例中,我们使用cv::calcHist()函数计算图像直方图,然后使用cv::normalize()函数将直方图归一化,使其适合于图像显示。最后,我们使用cv::line()函数在一个新的Mat对象上绘制直方图,并使用cv::imshow()函数显示它。 需要注意的是,这个示例只绘制了灰度图像直方图,如果需要绘制彩色图像直方图,则需要将彩色图像转换为HSV颜色空间,然后计算每个通道的直方图,并将它们组合成一个三维直方图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值