赞
踩
在计算机视觉中,几乎处处都使用直方图。对于阈值计算,我们使用灰度直方图。对于白平衡,我们使用直方图。对于图片中的对象跟踪,比如CamShift技术,我们使用颜色直方图,采用颜色直方图作为特征。
在更抽象的意义上,从梯度直方图形成 HOG 和 SIFT 描述符。
直方图也是一种视觉词袋表示,广泛用于图像搜索引擎和机器学习中。而且,这很可能不是您第一次在研究中看到直方图。
那么,为什么直方图会派上用场呢?
因为直方图描绘了一组数据频率分布。事实证明,查看这些频率分布是开发简单图像处理技术的主要方法…以及真正强大的机器学习算法。
这篇博文将总结图像直方图,以及如何使用 OpenCV 和 C++ 从视频中计算颜色直方图。
可以将直方图视为显示图像强度分布的图形。X 轴为像素值(通常范围为 0 到 255),Y 轴为图片中的像素数。
这只是查看图像的不同方式。当您查看图像的直方图时,您可能会感觉到图像的对比度、亮度、强度分布等。
今天几乎所有的图像处理软件都包含直方图功能。

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];
#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; }
cap.read()方法逐帧读取视频。bgr_planes.b_hist, g_hist, r_hist中。uniform和accumulate设置为true。histImage来显示我们的直方图。b_hist, g_hist, r_hist。
calHist函数接收以下参数
cv2.calcHist([img], channels, mask, bins, ranges)

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)


# 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)
# 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/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。