OpenCV+VS 之用直方图统计像素(中)直方图均衡化、反向投影直方图检测特定图像内容、用均值平移算法查找目标

图像处理与分析:直方图均衡化与内容检测
本文介绍了直方图均衡化技术及其在C++中的实现,用于改善图像的视觉效果。此外,探讨了利用直方图反向投影检测图像特定内容的方法,以检测图像中的云彩为例。最后,通过均值平移算法在HSV色彩空间中搜索目标,以定位物体。这些技术在图像处理和计算机视觉中有着广泛应用。

一、直方图均衡化

【实现】

#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;

int main()
{
	//读取输入的图像
	cv::Mat image = cv::imread("bluesky.jpg",0);
	cv::Mat result;
	cv::equalizeHist(image, result);
	cv::namedWindow("Equalized Image");
	cv::imshow("Equalized Image", result);
	cv::namedWindow("Original Image");
	cv::imshow("Original Image", image);
	cv::waitKey(0);
}

【实现原理】

        在一个完全均衡的直方图中,所有箱子所包含的像素数量是相等的。这意味着 50%像素的强度值小于128(强度中值),25%像素的强度值小于64,以此类推。这个现象可以用一条规则来表示:p%像素的强度值必须小于或等于255*p%。这条规则用于直方图均衡化处理,表示强度值i的映像对应强度值小于i的像素所占的百分比。因此可以用下面的语句构建所需的查找表:

         lookup.at(i)= static_cast(255.0*p[i]/image.total());

        这里的 p[i]是强度值小于或等于 i 的像素数量,通常称为累计直方图。这种直方图包含小于或等于指定强度值的像素数量,而非仅仅包含等于指定强度值的像素数量。前面说过image.total()返回图像的像素总数,因此 p[i]/image.total()就是像素数量的百分比。

        一般来说,直方图均衡化会大大改进图像外观,但是改进的效果会因图像可视内容的不同而不同。

二、反向投影直方图检测特定图像内容

        直方图是图像内容的一个重要特性。如果图像的某个区域含有特定的纹理或物体,这个区域 的直方图就可以看作一个函数,该函数返回某个像素属于这个特殊纹理或物体的概率。本节将介 绍如何运用直方图反向投影的概念方便地检测特定的图像内容。

【实现】

        假设你希望在某幅图像中检测出特定的内容(例如检测出下图中天上的云彩),首先要做的 就是选择一个包含所需样本的感兴趣区域。接着提取该 ROI 的直方图,归一化直方图,从归一化后的直方图中读取概率值并把输入图像中的每个像素替换成与之对应的概率值。得到的结果就是下面的概率分布图。为提高可读性,可以对图像做了反色处理(下面代码没有进行反色处理),属于该区域的概率从亮(低概率)到暗(高概率)。最后,对此图做阈值化处理,就能得到最有可能是“云彩”的像素。

#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;

//创建灰度图像的直方图
class Histogram1D {
private:
	int histSize[1];//直方图中箱子的数量
	float hranges[2];//值范围
	const float* ranges[1];//值范围的指针
	int channels[1];//要检查的通道数量
public:
	Histogram1D() {
		//准备一维直方图的默认参数
		histSize[0] = 256;//256个箱子
		hranges[0] = 0.0;//从0开始(含)
		hranges[1] = 256.0;//到256(不含)
		ranges[0] = hranges;
		channels[0] = 0;//先关注通道0
	}
	cv::Mat getHistogram(const cv::Mat& image);
	cv::Mat getHistogramImage(const cv::Mat& image, int zoom = 1);
	static cv::Mat getImageOfHistogram(const cv::Mat& hist, int zoom);
	cv::Mat getBackprojection(const cv::Mat& image);
};

//计算一维直方图
cv::Mat Histogram1D::getHistogram(const cv::Mat& image) {
	cv::Mat hist;
	//用calcHist函数计算一维直方图
	cv::calcHist(&image, 1,	//仅为一幅图像的直方图
		channels,	//使用的通道
		cv::Mat(),	//不使用掩码
		hist,		//作为结果的直方图
		1,			//这是一维的直方图
		histSize,	//箱子数量
		ranges		//像素值的范围
	);
	return hist;
}

//创建一个表示直方图的图像(静态方法)
cv::Mat Histogram1D::getImageOfHistogram(const cv::Mat& hist, int zoom) {
	//取得箱子值的最大值和最小值
	do
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值