calHist()-使用OpenCV和C++计算直方图

这篇具有很好参考价值的文章主要介绍了calHist()-使用OpenCV和C++计算直方图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

calHist()-使用OpenCV和C++计算直方图

在计算机视觉中,几乎处处都使用直方图。对于阈值计算,我们使用灰度直方图。对于白平衡,我们使用直方图。对于图片中的对象跟踪,比如CamShift技术,我们使用颜色直方图,采用颜色直方图作为特征。

在更抽象的意义上,从梯度直方图形成 HOG 和 SIFT 描述符。

直方图也是一种视觉词袋表示,广泛用于图像搜索引擎和机器学习中。而且,这很可能不是您第一次在研究中看到直方图。

那么,为什么直方图会派上用场呢?

因为直方图描绘了一组数据频率分布。事实证明,查看这些频率分布是开发简单图像处理技术的主要方法…以及真正强大的机器学习算法。

这篇博文将总结图像直方图,以及如何使用 OpenCV 和 C++ 从视频中计算颜色直方图。

1. 什么是直方图

可以将直方图视为显示图像强度分布的图形。X 轴为像素值(通常范围为 0 到 255),Y 轴为图片中的像素数。

这只是查看图像的不同方式。当您查看图像的直方图时,您可能会感觉到图像的对比度、亮度、强度分布等。

今天几乎所有的图像处理软件都包含直方图功能。

用opencv编写一个程序,能够计算图像中颜色的直方图,opencv,c++,计算机视觉

2. OpenCV C++实现

2.1 OpenCV 中的 calHist() 函数

cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

使用calHist函数来实现直方图,参数解析:

1. images:这是`uint8`或`float32`源图像。
1. channels:它是计算直方图的通道索引。如果输入是灰度图像,则值为[0]。要计算彩色图像中蓝色、绿色或红色通道的直方图,请传递[0] 、[1]或[2] 。
1. mask:计算直方图的区域,None表示整幅图像区域
1. histSize:Bin数目,必须用方括号括起来。传递[256]表示全像素范围
1. range:通常是[0,256];

2.2 代码

#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>


const int histSize = 256;

void drawHistogram(cv::Mat& b_hist,cv::Mat& g_hist,cv::Mat& r_hist)
{
    int hist_w = 512;
    int hist_h = 400;
    int bin_w = cvRound((double)hist_w / histSize);

    cv::Mat histImage(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0));

    cv::normalize(b_hist, b_hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
    cv::normalize(g_hist, g_hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
    cv::normalize(r_hist, r_hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());

    for (int i = 1; i < histSize; i++) 
    {
      cv::line(
          histImage,
          cv::Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
          cv::Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))),
          cv::Scalar(255, 0, 0), 2, 8, 0);
      cv::line(
          histImage,
          cv::Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
          cv::Point(bin_w * (i), hist_h - cvRound(g_hist.at<float>(i))),
          cv::Scalar(0, 255, 0), 2, 8, 0);
      cv::line(
          histImage,
          cv::Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
          cv::Point(bin_w * (i), hist_h - cvRound(r_hist.at<float>(i))),
          cv::Scalar(0, 0, 255), 2, 8, 0);
    }

    cv::namedWindow("calcHist Demo", cv::WINDOW_AUTOSIZE);
    cv::imshow("calcHist Demo", histImage);

}
int main(int argc, char **argv) 
{
  cv::Mat src, dst;

  cv::VideoCapture cap;
  if (argc != 2)
    cap.open(0);
  else
    cap.open(argv[1]);

  if (!cap.isOpened()) {
    std::cerr << "Failed to load webcam/Video ...\n";
    return -1;
  }

  for (;;) 
  {
    if(!cap.read(src)) 
    {
      std::cerr << "Cannot read file\n";
      break;
    }
    cv::imshow("Src", src);
    std::vector<cv::Mat> bgr_planes;
    cv::split(src, bgr_planes);


    float range[] = {0, 256};
    const float *histRange = {range};

    bool uniform = true;
    bool accumulate = false;

    cv::Mat b_hist, g_hist, r_hist;

    cv::calcHist(&bgr_planes[0], 1, 0, cv::Mat(), b_hist, 1, &histSize,
                 &histRange, uniform, accumulate);
    cv::calcHist(&bgr_planes[1], 1, 0, cv::Mat(), g_hist, 1, &histSize,
                 &histRange, uniform, accumulate);
    cv::calcHist(&bgr_planes[2], 1, 0, cv::Mat(), r_hist, 1, &histSize,
                 &histRange, uniform, accumulate);

    drawHistogram(b_hist,g_hist,r_hist);

    if (cv::waitKey(30) == 27)
      break;
  }

  return 0;
}

2.3 代码解析

  • 首先读取我们的输入文件,使用cap.read()方法逐帧读取视频。
  • 使用split()函数,将多通道数组(即 BGR)划分为单独的单通道数组,并将其存储在bgr_planes.
  • 然后我们计算每个通道的直方图并将值存储在变量b_hist, g_hist, r_hist中。
  • 在直方图中,我们希望我们的Bin具有相同的大小,并且我们希望在开始时清除我们的直方图,因此,我们将uniformaccumulate设置为true
  • 计算直方图后,我们创建一个图像histImage来显示我们的直方图。
  • 然后我们在每个通道的每个像素处使用cv::line绘制线,即b_hist, g_hist, r_hist

2.4 输出

用opencv编写一个程序,能够计算图像中颜色的直方图,opencv,c++,计算机视觉

3. OpenCV Python实现

3.1 灰度直方图

calHist函数接收以下参数

cv2.calcHist([img], channels, mask, bins, ranges)

  • 图像列表
  • 通道列表
  • mask
  • bins数目
  • ranges,例如[0, 255]

用opencv编写一个程序,能够计算图像中颜色的直方图,opencv,c++,计算机视觉

from matplotlib import pyplot as plt
import cv2 as cv

img = cv.imread('lego.png')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

hist = cv.calcHist([gray], [0], None, [256], [0, 256])

plt.figure()
plt.title('Grayscale histogram')
plt.xlabel('Bins')
plt.ylabel('# of pixels')
plt.plot(hist)
plt.xlim([0, 256])
plt.ylim([0, 2000])
plt.show()

cv.waitKey(0)

3.2 彩色直方图

用opencv编写一个程序,能够计算图像中颜色的直方图,opencv,c++,计算机视觉

用opencv编写一个程序,能够计算图像中颜色的直方图,opencv,c++,计算机视觉

# Color histogram
from matplotlib import pyplot as plt
import cv2 as cv

img = cv.imread('lego.png')
chans = cv.split(img)
colors = 'b', 'g', 'r'

plt.figure()
plt.title('Flattened color histogram')
plt.xlabel('Bins')
plt.ylabel('# of pixels')

for (chan, color) in zip(chans, colors):
    hist = cv.calcHist([chan], [0], None, [256], [0, 255])
    plt.plot(hist, color=color)
    plt.xlim([0, 256])
    plt.ylim([0, 1200])

plt.show()
cv.waitKey(0)

3.3 模糊案例

# Blurring
import cv2 as cv

def trackbar(x):
    x = cv.getTrackbarPos('blur x','window')
    y = cv.getTrackbarPos('blur x','window')
    blurred = cv.blur(img, (x, y))
    cv.imshow('window', blurred)
    cv.displayOverlay('window', f'blur = ({x}, {y})')

img = cv.imread('lego.png')
cv.imshow('window', img)
cv.createTrackbar('blur x', 'window', 0, 4, trackbar)
cv.createTrackbar('blur y', 'window', 0, 4, trackbar)

cv.waitKey(0)
cv.destroyAllWindows()

参考目录

https://opencv-tutorial.readthedocs.io/en/latest/histogram/histogram.html
https://anothertechs.com/programming/cpp/opencv/calculate-histogram/文章来源地址https://www.toymoban.com/news/detail-797239.html

到了这里,关于calHist()-使用OpenCV和C++计算直方图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OPENCV C++(十)gramm矫正+直方图均衡化

    两者都是只对单通道使用,对多通道的话 就需要分离通道处理再合并通道  两种方法,第一个要运算次数太多了,第二个只需要查表 伽马矫正函数,这里用第二种方法,且写法有点高级 就是建立了查找表,然后计算查找表,再遍历像素直接赋值查找表,就不用计算了。 这就

    2024年02月13日
    浏览(32)
  • OpenCV官方教程中文版 —— 直方图的计算,绘制与分析

    • 使用 OpenCV 或 Numpy 函数计算直方图 • 使用 Opencv 或者 Matplotlib 函数绘制直方图 • 将要学习的函数有:cv2.calcHist(),np.histogram() 什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度

    2024年02月06日
    浏览(34)
  • OpenCV-41 使用掩膜的直方图

    掩膜即为与原图大小一致的黑底白框图。 如何生成掩膜? 先生成一个全黑的和原始图片大小一样大的图片。mask = np.zeros(img.shape, np.uint8) 将想要的区域通过索引方式设置为255.mask[100:200, 200:300] 示例代码如下: 输出结果如下: 注意点: 0与任何东西进行与运算都为0 255与非0的进

    2024年02月20日
    浏览(30)
  • 使用OpenCV显示图像的RGB颜色直方图

    2024年02月13日
    浏览(37)
  • 【OpenCV学习笔记30】- OpenCV 中的直方图 - 直方图 - 4:直方图反投影

    这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔记的请麻烦帮我关注

    2024年03月26日
    浏览(41)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸监测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月10日
    浏览(37)
  • Opencv4基于C++基础入门笔记:图像 颜色 事件响应 图形 视频 直方图 Opencv4基于C++的 实时人脸检测

      效果图 ◕‿◕:opencv人脸识别效果图(请叫我真爱粉)✌✌✌先看一下效果图勾起你的兴趣!  文章目录: 一:环境配置搭建 二:图像 1.图像读取与显示 main.cpp  运行结果 2.图像色彩空间转换 2.1 换色彩  test.h  test.cpp main.cpp    运行结果 2.2 照片换背景 test.h        test.

    2024年02月13日
    浏览(40)
  • Opencv C++ 六、灰度变换:线性变换、灰度反转、对数变换、伽马变换、(自适应)直方图均衡化

    通过变换函数T将原图像像素灰度值r映射为灰度值s: s=T(r). 线性变换(亮度和对比度调整) : 原理:线性变换是一种简单的亮度和对比度调整方法,通过对每个像素的灰度级别应用线性变换公式来实现。对每个像素应用公式 output_pixel = input_pixel * alpha + beta ,其中 alpha 控制对

    2024年02月04日
    浏览(24)
  • C#使用OpenCv(OpenCVSharp)图像直方图均衡化处理实例

    本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行直方图均衡化处理。 直方图均衡化原理 直方图均衡化(Histogram Equalization)是一种常用的图像增强技术,用于改善图像的对比度和亮度分布。它通过重新分配图像灰度级的像素值,使得图像的直方图在灰度范围内更加

    2024年02月07日
    浏览(46)
  • OpenCV10-图像直方图:直方图绘制、直方图归一化、直方图比较、直方图均衡化、直方图规定化、直方图反射投影

    图像直方图就是统计图像中每个灰度值的个数,之后将灰度值作为横轴,以灰度值个数或者灰度值所占比率作为纵轴的统计图。通过直方图,可以看出图像中哪些灰度值数目较多,哪些较少,可以通过一定的方法将灰度值较为集中的区域映射到较为稀疏的区域,从而使图像在

    2024年01月16日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包