C++ opencv之图像直方图(calcHist)

本文介绍如何使用C++和OpenCV库计算图像直方图,包括bins的概念,代码演示,以及直方图的计算和显示过程。通过示例代码详细解释了从读取图像到绘制直方图的完整流程。
摘要由CSDN通过智能技术生成

这篇博客我们主要来学习图像直方图。
图像直方图是图像像素值的统计学特征、计算代价较小,具有图像平移、旋转、缩放不变性等众多优点,广泛地应用于图像处理的各个领域,特别是灰度图像的阈值分割、基于颜色的图像检索以及图像分类、反向投影跟踪。
Bins是指直方图的大小范围, 对于像素值取值在0~255之间的,最少有256个bin,此外还可以有16、32、48、128等,256除以bin的大小应该是整数倍。

calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);

一、代码演示

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

using namespace cv;
using namespace std;

const int bins = 256;
Mat src;
const char* winTitle = "input image";
void showHistogram();
void drawHistogram(Mat &image);
int main(int argc, char** argv) {
   
	src = imread("C:/Users/Dell/Desktop/picture/butterfly.jpg",IMREAD_GRAYSCALE);
	//若想处理源图,删掉这里的IMREAD_GRAYSCALE
	if (src.empty()) {
   
		printf("could not load image...\n");
		return 0;
	}
	namedWindow(winTitle, WINDOW_AUTOSIZE);
	imshow(winTitle, src);
	drawHistogram(src);
	waitKey(0);
	return 0;
}

void drawHistogram(Mat &image) {
   
	// 定义参数变量
	const int channels[1] = {
    0 };
	const int bins[1] = {
    256 };
	float hranges[2] = {
    0,255 };
	const float* ranges[1] = {
    hranges };
	int dims = image.channels();
	if (dims == 3) {
   
		vector<Mat> bgr_plane;
		split(src, bgr_plane);
		Mat b_hist;
		Mat g_hist;
		Mat r_hist;
		// 计算Blue, Green, Red通道的直方图
		calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);
		calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
		calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);
		// 显示直方图
		int hist_w = 512;
		int hist_h = 400;
		int bin_w = cvRound((double)hist_w / bins[0]);
		Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
		// 归一化直方图数据
		normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
		normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
		normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
		// 绘制直方图曲线
		for (int i = 1; i < bins[0]; i++)<
在计算机视觉和图像处理中,直方图是一个非常重要的概念,它可以帮助我们更好地理解和处理图像。在 OpenCV 中,可以使用函数 `calcHist()` 来计算图像直方图,该函数接收的参数包括图像、通道数、直方图尺寸、像素值范围等。具体的操作流程如下: 1. 读取图像并转换为灰度图像 2. 定义直方图的参数,包括通道数、直方图尺寸和像素值范围等 3. 计算直方图 4. 绘制直方图 下面是一个简单的代码示例: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 读取图像并转换为灰度图像 Mat srcImage = imread("lena.jpg", IMREAD_GRAYSCALE); // 定义直方图的参数 int histSize[] = { 256 }; float range[] = { 0, 256 }; const float* histRange[] = { range }; int channels[] = { 0 }; // 计算直方图 Mat hist; calcHist(&srcImage, 1, channels, Mat(), hist, 1, histSize, histRange); // 绘制直方图 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[0]; i++) { line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))), Scalar(255), 2, LINE_AA); } // 显示原始图像直方图 namedWindow("Source Image", WINDOW_AUTOSIZE); imshow("Source Image", srcImage); namedWindow("Histogram", WINDOW_AUTOSIZE); imshow("Histogram", histImage); waitKey(0); return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值