昊虹AI笔记网

 找回密码
 立即注册
搜索
查看: 746|回复: 0
收起左侧

利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图

[复制链接]

239

主题

241

帖子

931

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
931
昊虹君 发表于 2023-1-7 16:17 | 显示全部楼层 |阅读模式
利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图

在上一篇博文 https://www.hhai.cc/thread-200-1-1.html 中已经对OpenCV的直方图计算函数calcHist()进行了详细介绍。
这篇博文介绍如何用直方图数据绘制直方图。

OpenCV是没有统计图绘制的相关函数的,所以要么用第三方库,要么想另外的办法。

先说Python-OpenCV中如何用直方图数据绘制直方图,由于Python安装和导入扩展库是非常方便简单的,所以我们用扩展库Matplotlib来绘制图像的直方图。

关于扩展库Matplotlib的安装大家可以参见下面这篇博文:
https://www.hhai.cc/thread-64-1-1.html

关于扩展库Matplotlib的使用示例可以参考下面这篇博文:
https://www.hhai.cc/thread-210-1-1.html

示例代码如下:
  1. # -*- coding: utf-8 -*-
  2. # 出处:昊虹AI笔记网(hhai.cc)
  3. # 用心记录计算机视觉和AI技术

  4. # 博主微信/QQ 2487872782
  5. # QQ群 271891601
  6. # 欢迎技术交流与咨询

  7. # OpenCV的版本为4.4.0

  8. import cv2 as cv
  9. import matplotlib.pyplot as plt
  10. import sys

  11. if __name__ == '__main__':
  12.     # 读取图像并判断是否读取成功
  13.     img = cv.imread('E:/material/images/2022/2022-12/view1.jpg', 0)
  14.     if img is None:
  15.         print('Failed to read img.')
  16.         sys.exit()

  17.     cv.imshow('img', img)

  18.     hist1 = cv.calcHist([img], [0], None, [256], [0, 256])

  19.     plt.plot(hist1)

  20.     cv.waitKey(0)
  21.     cv.destroyAllWindows()
复制代码

运行结果如下:

                                          

从上面的直方图中,我们可以清晰的看出,图像的灰度数据值主要集中在40-70的范围内,所以整幅图像是偏暗的。

虽然C++中也有专门绘制统计图的库,但显然没有Python导入扩展库那么简单,并且在使用上数据的引用传递也是个麻烦事,所以在C++中,我们就用OpenCV自带的线段绘制函数line()进行图像直方图的绘制了。示例代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;


int main()
{
    // 图像获取及判断 
    cv::Mat Image, ImageGray;
    Image = cv::imread("E:/material/images/2022/2022-12/view1.jpg"); 
    if(Image.empty()) 
      return -1;
    cv::imshow("Image",Image);
    // 转换为灰度图像
    cv::cvtColor(Image,ImageGray,CV_BGR2GRAY);
    // 定义直方图参数
    const int channels[1]={0};
    const int histSize[1]={256};
    float pranges[2]={0,256};
    const float* ranges[1]={pranges};
    cv::MatND hist;
    // 计算直方图
    cv::calcHist(&ImageGray,1,channels,cv::Mat(),hist,1,
    histSize,ranges);
    // 初始化画布参数
    int hist_w = 500; 
    int hist_h = 500;
    int nHistSize = 255;
    // 区间
    int bin_w = cvRound( (double) hist_w / nHistSize );
    cv::Mat histImage( hist_w, hist_h,
             CV_8UC3,   cv::Scalar( 0,0,0) );
	  // 将直方图归一化到范围 [ 0, histImage.rows ]
	  normalize(hist, hist, 0, histImage.rows, 
               cv::NORM_MINMAX,  -1, cv::Mat() );
	  // 在直方图画布上画出直方图
    for( int i = 1; i < nHistSize; i++ )
    {
      line( histImage, cv::Point(bin_w*(i-1),
             hist_h-cvRound(hist.at<float>(i-1)) ) ,
             cv::Point( bin_w*(i), 
             hist_h - cvRound(hist.at<float>(i)) ),
             cv::Scalar( 0, 0, 255), 2, 8, 0  );
    }
    // 显示直方图
    cv::imshow("histImage", histImage);
    cv::waitKey();
    return 0;
}

运行结果如下图所示:


把Python代码的运行结果和C++代码的运行结果放在一起对比如下:

从上图可以看出,二者其实是相同的,只是因为Python的Matplotlib库是专业的统计绘图库,所以显然要专业的多。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|昊虹AI笔记网 ( 蜀ICP备2024076726 )

GMT+8, 2024-5-18 14:43 , Processed in 0.026268 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表