您的位置:首页 > 编程语言 > C语言/C++

基于opencv和c++的图像处理:直方图均衡化

2012-10-27 12:46 686 查看
一般而言,图片有RGB三通道,每个通道用一个byte表示,取值范围在0到255之间。对于每个通道,我们都可以计算图像的直方图,其实就是统计每个像素值的出现频率,如下图所示:



直方图均衡化的效果,即把原图的三通道的直方图变成均匀分布,每种像素值出现的次数都差不多,下面是直方图均衡化后的效果(直方图是用光影查看的,生成效果图的代码见后):




可以看到,图片的直方图很均匀。

直方图均衡化的代码:

bool GFImage::HistogramEqualization()
{
	vector<vector<uchar> > pixMaps;
	CalculateMapFunByHisEq(pixMaps);
	for (int ch = 0; ch < GetChannel(); ch++)
	{
		uchar * pData = GetData();
		for (int r = 0;r < GetHeight(); r++)
		{
			uchar * pLine = pData + r * GetWidthStep();
			for (int c = 0; c < GetWidth(); c++)
			{
				uchar val = pLine[GetChannel() * c + ch];
				pLine[GetChannel() * c + ch] = pixMaps[ch][val];
			}
		}
	}
	return true;
}


bool GFImage::CalculateMapFunByHisEq(vector<vector<uchar> >& vMappings) const
{
	vMappings.resize(GetChannel());
	for (int i = 0; i < vMappings.size(); i++)
	{
		vMappings[i].resize(256);
	}

	vector<GFHistogram> vHistograms;
	vHistograms.resize(GetChannel());
	for (int i = 0;i < GetChannel(); i++)
	{
		vHistograms[i].Calculate(*this, 256, i);
	}
	double tmp;
	for (int ch = 0; ch < GetChannel(); ch++)
	{
		tmp = vHistograms[ch].GetFrequencyAt(0) * 255;
		vMappings[ch][0] = (uchar)tmp;
		for (int j = 1;j < 256; j++)
		{
			tmp = tmp + vHistograms[ch].GetFrequencyAt(j) * 255;
			vMappings[ch][j] = (uchar)tmp;
		}
	}
	return true;
}


调用时

string strImagePath = "lena.jpg";
GFImage image1(strImagePath);
image1.ShowImage("ori");
image1.HistogramEqualization();
image1.ShowImage("res");
cv::waitKey();


其中GFImage封装了opencv的图像类,GFHistogram是自定义的直方图类。详细代码可参考这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: