opencv c++ 图像直方图(24)

博客介绍了图像直方图,它是对图像中各像素点值的统计,在图像平移、旋转、缩放等操作时反馈不变,可广泛用于图像处理领域。还提到了直方图的大小范围Bins,以及给出了相关API参数、代码示例和结果。

图像直方图:

对图像中各个像素点点值的统计(即对每段像素值计算其出现次数)。

在对图像进行平移、旋转、缩放等操作时,其直方图反馈不会变,故此直方图能广泛应用于图像处理各个领域。

Bins:

直方图的大小范围,像素取值范围0~255时,最少有256个bin,256除以bin的大小应是整数结果。

API

calcHist(const  Mat * images,  int  nimages, const int *  channels, InputArray mask, OutputArray hist, int  dims, const int *  histSize, const float **  ranges, bool  uniform true, bool  accumulate false )

Parameters

images输入图像Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same size. Each of them can have an arbitrary number of channels.
nimages图像数量Number of source images.
channels通道数(输入为0时表示只有1个通道,如果有多个通道需要定义数组)
mask特定图像中需要绘制直方图的区域
hist输出Output histogram, which is a dense or sparse dims -dimensional array.
dims维度Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS (equal to 32 in the current OpenCV version).
histSize对应维度里的直方图像素值尺寸Array of histogram sizes in each dimension.
ranges像素值范围
uniformFlag indicating whether the histogram is uniform or not (see above).
accumulateAccumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time.

直方图示例:

 代码:

void QuickDemo::histogram_demo(Mat& image)
{
	// 三通道分离
	std::vector<Mat> bgr_plane;
	split(image, bgr_plane);
	// 定义参数变量
	const int channels[1] = { 0 };
	const int bins[1] = { 256 };
	float hranges[2] = { 0,255 };
	const float* ranges[1] = { hranges };
	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++) {
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);
		line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);
	}
	// 显示直方图
	namedWindow("Histogram Demo", WINDOW_AUTOSIZE);
	imshow("Histogram Demo", histImage);
}

结果:

### 如何使用 OpenCV C++ 实现图像直方图处理 #### 计算并绘制单通道灰度图像直方图 为了计算和显示一幅灰度图像直方图,可以采用如下代码: ```cpp #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main(int argc, char** argv){ Mat srcImage = imread(argv[1], IMREAD_GRAYSCALE); // 加载输入图片作为灰度模式 if(srcImage.empty()){ cout << "Could not open or find the image!" << endl ; return -1; } int histSize = 256; // 直方图柱数等于像素强度级别数量 float range[] = {0, 256}; // 设置亮度范围 const float* histRange = {range}; bool uniform = true, accumulate = false; Mat hist; calcHist(&srcImage, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate); double maxVal=0; minMaxLoc(hist, 0, &maxVal, 0, 0); int scale = 2; Mat histImg = Mat::zeros(100*scale, 256*scale, CV_8UC3); for(int i = 0 ;i<histSize;i++){ line(histImg, Point(i*scale,(100-maxVal)*scale), Point((i+1)*scale,(100-maxVal)*scale), Scalar(255,0,0),1,8,0); } flip(histImg,histImg,0); imshow("Histogram", histImg); waitKey(); } ``` 上述程序展示了如何读取一张灰度图,并调用 `cv::calcHist()` 函数来获取其直方图数据。接着创建了一个空白画布用于可视化这些统计数据。 #### 归一化直方图 对于某些应用来说,可能希望得到的是概率密度形式而不是绝对频率计数值,在这种情况下就需要对原始直方图执行归一化操作: ```cpp Mat normalizedHist; normalize(hist, normalizedHist, alpha=0, beta=1, norm_type=NORM_MINMAX); // 这里alpha代表最小值,beta最大值,NORM_MINMAX表示线性变换到指定区间内. ``` 此段落中的`normalizedHist`即为经过标准化后的版本[^2]。 #### 应用场景举例:直方图均衡化 当面对低对比度的照片时,可以通过调整各强度级别的分布使得整体视觉效果更佳清晰锐利。这正是所谓的直方图均衡化的意义所在。下面给出一段简单的实现方式: ```cpp equalizeHist(srcImage,dstImage); imshow("Equalized Image", dstImage); waitKey(); ``` 这段简短却强大的命令能够自动优化给定源影像内的色调层次结构从而提升最终呈现出来的观感质量[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值