简单

行远必自迩,登高必自卑

[图像处理]直方图均衡化

直方图均衡化

概念

直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非 线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一 个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。 直方图是表示数字图像中每一灰度出现频率的统计关系。直方图能给出图像灰度范围、 每个灰度的频度和灰度的分布、整幅图像的平均明暗和对比度等概貌性描述。灰度直方图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数, 其横坐标是灰度级 r, 纵坐 标是该灰度级出现的频率( 即像素的个数) pr( r) , 整个坐标系描述的是图像灰度级的 分布情况, 由此可以看出图像的灰度分布特性, 即若大部分像素集中在低灰度区域, 图 像呈现暗的特性; 若像素集中在高灰度区域, 图像呈现亮的特性。 由于这个算法只是算了灰度图像,所以加入处理彩色图像,只需要对图像 R G B 每个分量 进行直方图累计后拓展,后找到映射关系。

算法

arithmetic

示例

处理前

处理后

源码

///////////////////////////////////////////////////
// 程序名称:图像处理——直方图均衡化
// 编译环境:Mictosoft Visual Studio 2013, EasyX_20200315(beta)
// 作  者:luoyh <2864292458@qq.com>
// 最后修改:2020-11-27
//

#include<graphics.h>
#include<conio.h>

class Algorithm
{
public:
	Algorithm(IMAGE *img, int width, int heigth);
	void Histogram();				// 直方图
private:
	IMAGE *pimg;
	int WIDTH;
	int HEIGHT;
};

Algorithm::Algorithm(IMAGE *img, int width, int height)
{
	pimg = img;
	WIDTH = width;
	HEIGHT = height;
};

void Algorithm::Histogram()		// 直方图
{
	DWORD*	p_data = GetImageBuffer(pimg);
	int height = HEIGHT;
	int wide = WIDTH;
	double pr[256], pg[256], pb[256];
	int size = HEIGHT * WIDTH;
	for (int p = 0; p <= 255; p++)
	{
		int nr = 0, ng = 0, nb = 0;
		for (int j = 0; j < height; j++)
		{
			for (int i = 0; i < wide; i++)
			{
				if (p == GetRValue(p_data[j*wide + i]))
				{
					nr++;
				}
				if (p == GetGValue(p_data[j*wide + i]))
				{
					ng++;
				}
				if (p == GetBValue(p_data[j*wide + i]))
				{
					nb++;
				}
			}
		}
		pr[p] = nr;
		pg[p] = ng;
		pb[p] = nb;
	}
	double sr[256] = { 0 }, sg[256] = { 0 }, sb[256] = { 0 };
	double aver = 0;
	double aveg = 0;
	double aveb = 0;
	for (int i = 0; i <= 255; i++)
	{
		aver += pr[i] / size;
		sr[i] = aver;
		aveg += pg[i] / size;
		sg[i] = aveg;
		aveb += pb[i] / size;
		sb[i] = aveb;
	}
	double ssr[255] = { 0 }, ssg[255] = { 0 }, ssb[255] = { 0 };
	for (int i = 0; i < 255; i++)
	{
		ssr[i] = (int)(((255 - 1) - 0) * sr[i] + 0.5);
		ssg[i] = (int)(((255 - 1) - 0) * sg[i] + 0.5);
		ssb[i] = (int)(((255 - 1) - 0) * sb[i] + 0.5);
	}
	int r = 0, g = 0, b = 0;
	double myr = 0, myg = 0, myb = 0;
	for (int j = 0; j < height; j++)
	{
		for (int i = 0; i < wide; i++)
		{
			while (GetRValue(p_data[j * wide + i]) != r)
			{
				r++;
				if (r == 255)
					break;
			}
			if (GetRValue(p_data[j * wide + i]) == r)
			{
				myr = ssr[r];
			}
			r = 0;
			while (GetGValue(p_data[j * wide + i]) != g)
			{
				g++;
				if (g == 255)
					break;
			}
			if (GetGValue(p_data[j * wide + i]) == g)
			{
				myg = ssg[g];
			}
			g = 0;
			while (GetBValue(p_data[j * wide + i]) != b)
			{
				b++;
				if (b == 255)
					break;
			}
			if (GetBValue(p_data[j * wide + i]) == b)
			{
				myb = ssb[b];
			}
			b = 0;
			p_data[j * wide + i] = RGB(myr, myg, myb);
		}
	}
};

int main()
{
	int	width = 0;
	int	height = 0;
	IMAGE g_img;
	loadimage(&g_img, _T("src.jpg"));	// 加载图片
	width = g_img.getwidth();
	height = g_img.getheight();
	initgraph(width, height);
	putimage(0,0,&g_img);
	_getch();
	Algorithm myA(&g_img, width, height);
	myA.Histogram();
	putimage(0, 0, &g_img);
	_getch();
	return 0;
}

作 者:简 单

Q  Q: 2864292458

邮 箱:2864292458@qq.com

分享到

添加评论