OpenCV-绘制简易直方图DrawHistImg

简介: OpenCV-绘制简易直方图DrawHistImg

需求说明

      在对图像进行处理时,经常会有这类需求:想要观察图像的直方图分布,例如灰度图中0-255区间数值的分布情况,从而可以进行后续的操作,如阈值分割二值化、直方图均衡化等等。本文设计了一个能绘制简易直方图的简单函数DrawHistImg,可以帮助大家快速掌握绘制的原理,可以根据自己的创意对其进行改善和补充。


      下面介绍具体实现流程。

具体流程

      1)取图像的灰度图,并遍历统计0-255各个灰度值所出现的次数。

cv::Mat src = imread("test.jpg", 0);
cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1);
for (int i = 0; i < src.rows; ++i)
{
  for (int j = 0; j < src.cols; ++j)
  {
    hist.at<float>(0, src.at <uchar>(i, j))++;
  }
}

      2)定义直方图图像histImage,并初始化一些参数。其中bins是数值最大值,即255;scale为每个灰度值所对应的直方图宽度;histHeight为直方图高度最大值,也是直方图图像的宽。

cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1);
const int bins = 255;
int scale = 4;
int histHeight = 540;

      3)利用minMaxLoc函数得出哪个灰度值的出现次数最高,为归一化做准备。

double maxValue;
cv::Point2i maxLoc;
cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc);

    4)遍历hist中每个灰度值,并根据其出现次数绘制直方图,height是归一化后的高度。

for (int i = 0; i < bins; i++)
{
  float binValue = (hist.at<float>(i));
  int height = cvRound(binValue * histHeight / maxValue);
  cv::rectangle(histImage, cv::Point(i * scale, histHeight),
    cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1);
}

      5)函数执行完毕。

功能函数

// 绘制简易直方图
cv::Mat DrawHistImg(cv::Mat &src)
{
  cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1);
  for (int i = 0; i < src.rows; ++i)
  {
    for (int j = 0; j < src.cols; ++j)
    {
      hist.at<float>(0, src.at <uchar>(i, j))++;
    }
  }
  cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1);
  const int bins = 255;
  double maxValue;
  cv::Point2i maxLoc;
  cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc);
  int scale = 4; 
  int histHeight = 540;
  for (int i = 0; i < bins; i++)
  {
    float binValue = (hist.at<float>(i));
    int height = cvRound(binValue * histHeight / maxValue);
    cv::rectangle(histImage, cv::Point(i * scale, histHeight),
      cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1);
  }
  return histImage;
}

C++测试代码

#include <iostream>
#include <time.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
cv::Mat DrawHistImg(cv::Mat &hist);
int main()
{
  cv::Mat src = imread("test.jpg", 0);
  // 绘制均衡化后直方图
  cv::Mat hrI = DrawHistImg(src);
  imshow("original", src);
  imshow("hist", hrI);
  waitKey(0);
  return 0;
}
// 绘制简易直方图
cv::Mat DrawHistImg(cv::Mat &src)
{
  cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1);
  for (int i = 0; i < src.rows; ++i)
  {
    for (int j = 0; j < src.cols; ++j)
    {
      hist.at<float>(0, src.at <uchar>(i, j))++;
    }
  }
  cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1);
  const int bins = 255;
  double maxValue;
  cv::Point2i maxLoc;
  cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc);
  int scale = 4; 
  int histHeight = 540;
  for (int i = 0; i < bins; i++)
  {
    float binValue = (hist.at<float>(i));
    int height = cvRound(binValue * histHeight / maxValue);
    cv::rectangle(histImage, cv::Point(i * scale, histHeight),
      cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1);
  }
  return histImage;
}

测试效果

图1 原图

图2 灰度图

图3 直方图

      如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
17天前
|
算法 Serverless 计算机视觉
opencv 直方图处理(python)
opencv 直方图处理(python)
|
5月前
|
计算机视觉
用openCV做统计直方图
用openCV做统计直方图
21 0
|
8月前
|
算法 安全 机器人
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++)
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++)
42 0
|
11月前
|
API 计算机视觉 Python
OpenCV_07 直方图:灰度直方图+直方图均衡化
直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实现定义好的 bin 当中。其中, bin 为直方图中经常用到的一个概念,可以译为 “直条” 或 “组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。
125 0
|
API 计算机视觉
opencv之直方图比较图像相似度
对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间 然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进 而比较图像本身的相似程度。
346 0
opencv之直方图比较图像相似度
|
图形学 计算机视觉 Python
Opencv 图像处理:图像通道、直方图与色彩空间
Opencv 图像处理:图像通道、直方图与色彩空间
138 0
Opencv 图像处理:图像通道、直方图与色彩空间
|
算法 计算机视觉
Python-OpenCV图像处理-11-图像的直方图的反向投影
Python-OpenCV图像处理-11-图像的直方图的反向投影
117 0
|
计算机视觉
Python-OpenCV图像处理-10-直方图的操作
Python-OpenCV图像处理-10-直方图的操作
136 0
|
API 计算机视觉 索引
OpenCV 直方图反向投影
OpenCV 直方图反向投影
151 0
OpenCV 直方图反向投影
|
API 计算机视觉
OpenCV 直方图比较
OpenCV 直方图比较
228 0
OpenCV 直方图比较