【OpenCV】直方图以及灰度直方图C++的实现

8 篇文章 0 订阅

在分析图像、物体和视频信息的时候,我们经常用直方图来表达我们关注的信息。直方图在计算机视觉中应用广泛。例如,通过判断帧与帧之间边缘和颜色的统计量是否出现巨大变化,来检测视频中场景的变换。
直方图只是简单地将数据归入预定义的组,并在每个组内进行计数。也可以选择对数据提取特征、再对特征进行计数,这里的特征可以是梯度的长度、梯度的方向、颜色或者其他任何可以反映数据特点的特征,也就是说,直方图是一种用来揭示数据分布的统计特性的工具。直方图的维度通常比原始数据的维度低。
OpenCV中使用数组来表示直方图,这里的数组和用来表示其他数据额数组没有任何区别。这意味着对于一维或二维数组,你可以使用cv::Mat(NX1或者1XN来表示一维数组),也可以使用vector<>或稀疏矩阵类型。当我们把一个数组视为直方图时,它就具有和普通数组完全不同的含义。例如,若一个n维数组被视为直方图,数组中的每个元素表达的是该n维直方图中对应组中的计数结果。而直方图中组的编号就是数组某维与其该组对应的元素的下标,它们通常都是整数。
OpenCV中使用cv::calcHist()从数据创建直方图

什么是灰度直方图:
在数字图像处理中,灰度直方图是一种计算代价非常小但很有用的工具,它概括了一幅图像的灰度级信息。灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。

c++代码如下:

Mat calcGrayHist(const Mat & image)
{
	Mat histogram = Mat::zeros(Size(256,1),CV_32SC1);    	 //256对应的是0~255共计256个像素值
													  		 //注意,Size对应的是x和y,也就是第一个元数是矩阵的列数
	int rows = image.rows;   	 //输入图像的行数
	int cols = image.cols;		 //输入图像的列数

	for(int r =0;r<rows;r++)
	{
		for(int c = 0;c<cols;c++)
		{
			int index = int(image.at<uchar>(r,c);	//获取每个点的像素值
			histogram.at<int>(0,index) +=1;			//获取了一个像素值,在相应的位置上加1
		}
	}
	return histogram;
}

图像对比度是通过灰度级范围来度量的,而灰度级范围可通过观察灰度直方图得到,灰度级范围越大代表对比度越高;反之,对比度越低,低对比度的图像在视觉上给人的感觉是看起来不够清晰。

**OpenCV C++灰度直方图** OpenCV是一个用于计算机视觉、图像处理以及机器学习领域的开源库。其中,灰度直方图是图像处理的一个重要工具,它可以帮助我们了解图像中像素值的分布情况。 ### 灰度直方图的概念 灰度直方图是一种统计图像中各个灰度级别的频率分布图表。每个直方图条表示某个灰度级别在图像中出现的次数。通常,灰度值范围从0到255,其中0代表黑色,255代表白色。 ### OpenCV计算灰度直方图的步骤 1. **读取图像**:首先需要使用OpenCV的`imread()`函数读取图片文件,并将其转换为灰度图。这是因为灰度直方图仅依赖于图像的亮度信息,而不需要颜色信息。 ```cpp cv::Mat image = cv::imread("path_to_image.jpg", cv::IMREAD_GRAYSCALE); ``` 2. **创建直方图向量**:OpenCV提供了一个内置的函数`cv::HistogramOfGrayscale`来创建灰度直方图向量。 ```cpp int histSize = 256; // 假设灰度级范围从0到255 float range[] = {0, 256}; // 区间[0, 256] const float* histRange = {range}; bool useValueCounts = true; std::vector<cv::Mat> histograms(1); // 创建一个单通道直方图向量 cv::calcHist(&image, 1, 0, cv::Mat(), histograms, 1, &histSize, &histRange, false, useValueCounts); ``` 3. **绘制直方图**:利用OpenCV的`imshow()`函数可以显示直方图。同时,也可以使用`plot()`函数直接在MATLAB环境下绘图,或者使用第三方库如matplotlib等。 ```cpp cv::namedWindow("Gray Histogram", cv::WINDOW_AUTOSIZE); cv::imshow("Gray Histogram", histograms); ``` ### 相关问题: 1. **如何优化计算大尺寸图像的灰度直方图性能?** - 可以通过减少采样点的数量来降低计算复杂度,例如只计算每行的前几个像素作为采样的代表值。 2. **如何调整OpenCV中的直方图计算窗口大小以提高精确度?** - 更改`histSize`变量的值可以调整直方图的精度,更小的值将导致更高的精度,但可能会增加噪声影响。 3. **OpenCV中如何对特定区域的图像进行局部灰度直方图分析?** - 使用`cv::Rect`结构体来指定ROI(Region of Interest),然后对该区域内的图像执行相同的直方图操作过程。这可以通过先裁剪ROI部分再进行后续处理来完成。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值