OpenCV--021:直方图规定化

直方图规定化


就是通过一个灰度映像函数,将原灰度直方图改造成所希望的直方图。所以直方图修正的关键就是灰度映像函数。


直方图规定化是用于产生处理后有特殊直方图的图像方法。

直方图均衡化能自动增强图像的整体对比度,但是往往结果难以受到控制。实际中常常需要增强某个特定灰度值范围内的对比度或使图像灰度值的分布满足特定需求。这个时候使用直方图规定化会有较好的结果。

直方图规定化就是要调整原始图像的直方图去逼近规定的目标直方图。M为原始图的灰度级数,N为目标图的灰度级数,且M>N。




直方图规定化的基本原理


根据直方图均衡化理论,首先对原始图像进行直方图均衡化处理.即求变换函数


s = T ( r ) = ∫ 0 r P r ( x ) d x s=T(r)=\int_0^rP_r(x)dx s=T(r)=0rPr(x)dx

现假定直方图规定化的目标图像已经实现,因此,对于目标图像也采用同样的方法进行均衡化处理,因而:


v = G ( z ) = ∫ 0 z P z ( x ) d x v=G(z)=\int_0^zP_z(x)dx v=G(z)=0zPz(x)dx

上式的逆变换为


z = G − 1 ( v ) z=G^{-1}(v) z=G1(v)

上式表明,可通过均衡化后的灰度级v求出目标函数的灰度级z。由于对目标图像和原始图像都进行了均衡化处理,因此具有相同的分布密度,即


P s ( s ) = P v ( v ) P_s(s)=P_v(v) Ps(s)=Pv(v)

因而可以用原始图像均衡化以后的灰度级s代表v,即


z = G − 1 ( v ) = G − 1 ( s ) z=G^{-1}(v)=G^{-1}(s) z=G1(v)=G1(s)

所以可以依据原始图像均衡化后的图像的灰度值得到目标图像的灰度级z。



直方图规定化方法


直方图规定化处理的一般步骤是:

  1. 根据直方图均衡化原理,对原图像的直方图进行灰度均衡化处理。
  2. 按照目标图像的概率密度函数 P z ( z ) P_z(z) Pz(z),求解目标图像进行均衡化处理的变换函数 G ( z ) G(z) G(z);
  3. 用原始图像均衡化中得到的灰度级s代替v,求解逆变换 z = G − 1 ( s ) z=G^{-1}(s) z=G1(s).

经过上述处理得到的目标图像的灰度级将具有事先规定的概率密度 P z ( z ) P_z(z) Pz(z)。上述变换过程中所包含的两个变换函数 T ( r ) T(r) Tr G − 1 ( s ) G^{-1}(s) G1(s)可形成复合函数,即可表示为


z = G − 1 ( s ) = G − 1 [ T ( r ) ] z=G^{-1}(s)=G^{-1}[T(r)] z=G1(s)=G1[T(r)]

由此可知,无需进行直方图均衡化运算就可以直接实现直方图规定化处理,通过复合函数关系有效的简化了直方图规定化处理过程,求出 T ( r ) T(r) T(r) G − 1 ( s ) G^{-1}(s) G1(s)之间的复合函数关系就可以直接对原始图像进行变换。


举例


假设一幅大小为64像素(MN=4096)的3比特图像(L=8)的灰度分布如表3.1所示,其中灰度级范围[0,L-1]=[0,7]中的整数。

表3.1 大小为64*64像素的3比特数字图像的灰度分布和直方图值
r k r_k rk n k n_k nk p r ( r k ) = n k / M N p_r(r_k)=n_k/MN pr(rk)=nk/MN
r 0 r_0 r07900.19
r 1 r_1 r110230.25
r 2 r_2 r28500.21
r 3 r_3 r36560.16
r 4 r_4 r43290.08
r 5 r_5 r52450.06
r 6 r_6 r61220.03
r 7 r_7 r7810.02

假设图像的直方图如图3.19(a)所示。直方图累计函数分布:
s 0 = T ( r 0 ) = 7 ∑ j = 0 0 p r ( r j ) = 7 p r ( r 0 ) = 1.33 s_0=T(r_0)=7\sum_{j=0}^{0} p_r(r_j)=7p_r(r_0)=1.33 s0=T(r0)=7j=00pr(rj)=7pr(r0)=1.33 s 1 = T ( r 1 ) = 7 ∑ j = 0 1 p r ( r j ) = 7 p r ( r 0 ) + 7 p r ( r 1 ) = 7 ∗ 0.19 + 7 ∗ 0.25 = 3.08 s_1=T(r_1)=7\sum_{j=0}^{1}p_r(r_j)=7p_r(r_0)+7p_r(r_1)=7*0.19+7*0.25=3.08 s1=T(r1)=7j=01pr(rj)=7pr(r0)+7pr(r1)=70.19+70.25=3.08 s 2 = T ( r 2 ) = 7 ∑ j = 0 2 p r ( r j ) = 7 p r ( r 0 ) + 7 p r ( r 1 ) + 7 p r ( r 2 ) = 7 ∗ 0.19 + 7 ∗ 0.25 + 7 ∗ 0.21 = 4.55 s_2=T(r_2)=7\sum_{j=0}^{2}p_r(r_j)=7p_r(r_0)+7p_r(r_1)+7p_r(r_2)=7*0.19+7*0.25+7*0.21=4.55 s2=T(r2)=7j=02pr(rj)=7pr(r0)+7pr(r1)+7pr(r2)=70.19+70.25+70.21=4.55
······
类似可得出:
s 3 = 5.67 , s 4 = 6.23 , s 5 = 6.65 , s 6 = 6.86 , s 7 = 7.00 s_3=5.67,s_4=6.23,s_5=6.65,s_6=6.86,s_7=7.00 s3=5.67,s4=6.23,s5=6.65,s6=6.86,s7=7.00
该变换函数的形状为阶梯状态,如图3.19(b)。


由于s是由概率和求得,所以它一直是一个小数,因此要把它们改成最接近的整数:

s k s_k sk G ( z k ) G(z_k) G(zk)
s 0 s_0 s01
s 1 s_1 s13
s 2 s_2 s25
s 3 s_3 s36
s 4 s_4 s46
s 5 s_5 s57
s 6 s_6 s67
s 7 s_7 s77

这些是均衡后的直方图的值。很明显,只有5个不同的灰度级。因为 r 0 = 0 r_0=0 r0=0被映射为 s 0 = 1 s_0=1 s0=1,在均衡后的图像中有790个像素具有该值(见表3.1)。另外,在图像中有1023个像素取 s 1 = 3 s_1=3 s1=3这个值,有850个像素取 s 2 = 5 s_2=5 s2=5这个值。由于 r 3 r_3 r3 r 4 r_4 r4都被映射为同一个值6,所以均衡后的图像中有(656+329)=985个像素取这个值。类似的,在均衡后的图像中有(245+122+81)=448个像素取7这个值。
均衡后直方图取值:

表3.11
s k s_k sk n k n_k nk p k ( s k ) = n k / M N p_k(s_k)=n_k/MN pk(sk)=nk/MN
s 0 = 1 s_0=1 s0=17900.19
s 1 = 3 s_1=3 s1=310230.25
s 2 = 5 s_2=5 s2=58500.21
s 3 , 4 = 6 s_{3,4}=6 s3,4=69850.24
s 5 , 6 , 7 = 7 s_{5,6,7}=7 s5,6,7=74480.11

在这里插入图片描述
再次考虑上面64*64的假设图像,其直方图重复显示在图3.22(a)中。希望变换该直方图,以便使其具有表3.2中第二列规定的值。图3.22(b)显示了该直方图的大概形状。

表3.2 规定直方图和实际直方图
z q z_q zq规定的 p z ( Z q ) p_z(Z_q) pz(Zq)
z 0 = 0 z_0=0 z0=00.00
z 1 = 1 z_1=1 z1=10.00
z 2 = 2 z_2=2 z2=20.00
z 3 = 3 z_3=3 z3=30.15
z 4 = 4 z_4=4 z4=40.20
z 5 = 5 z_5=5 z5=50.30
z 6 = 6 z_6=6 z6=60.20
z 7 = 7 z_7=7 z7=70.15

计算直方图均衡后的累计分布值:

G ( z 0 ) = 7 ∑ j = 0 0 p z ( z j ) = 7 ∗ 0.00 = 0.00 G(z_0)=7\sum_{j=0}^{0}p_z(z_j)=7*0.00=0.00 G(z0)=7j=00pz(zj)=70.00=0.00
G ( z 1 ) = 7 ∑ j = 0 1 p z ( z j ) = 7 ∗ 0.00 + 7 ∗ 0.00 = 0.00 G(z_1)=7\sum_{j=0}^{1}p_z(z_j)=7*0.00+7*0.00=0.00 G(z1)=7j=01pz(zj)=70.00+70.00=0.00
G ( z 2 ) = 7 ∑ j = 0 2 p z ( z j ) = 0 G(z_2)=7\sum_{j=0}^{2}p_z(z_j)=0 G(z2)=7j=02pz(zj)=0
G ( z 3 ) = 7 ∑ j = 0 3 p z ( z j ) = 7 ∗ 0.15 = 1.05 G(z_3)=7\sum_{j=0}^{3}p_z(z_j)=7*0.15=1.05 G(z3)=7j=03pz(zj)=70.15=1.05
G ( z 4 ) = 7 ∑ j = 0 4 p z ( z j ) = 7 ∗ 0.15 + 7 ∗ 0.20 = 2.45 G(z_4)=7\sum_{j=0}^{4}p_z(z_j)=7*0.15+7*0.20=2.45 G(z4)=7j=04pz(zj)=70.15+70.20=2.45
G ( z 5 ) = 7 ∑ j = 0 5 p z ( z j ) = 7 ∗ 0.15 + 7 ∗ 0.20 + 7 ∗ 0.3 = 4.55 G(z_5)=7\sum_{j=0}^{5}p_z(z_j)=7*0.15+7*0.20+7*0.3=4.55 G(z5)=7j=05pz(zj)=70.15+70.20+70.3=4.55
G ( z 6 ) = 7 ∑ j = 0 6 p z ( z j ) = 4.55 + 7 ∗ 0.20 = 5.95 G(z_6)=7\sum_{j=0}^{6}p_z(z_j)=4.55+7*0.20=5.95 G(z6)=7j=06pz(zj)=4.55+70.20=5.95
G ( z 7 ) = 7 ∑ j = 0 7 p z ( z j ) = 5.95 + 7 ∗ 0.15 = 7.00 G(z_7)=7\sum_{j=0}^{7}p_z(z_j)=5.95+7*0.15=7.00 G(z7)=7j=07pz(zj)=5.95+70.15=7.00

把这些分数值转换为有效区间[0,7]内的整数。结果是:
在这里插入图片描述
结果形成表3.3,则可得变换函数3.22©。

表3.3
z q z_q zq G ( z q ) G(z_q) G(zq)
z 0 z_0 z00
z 1 z_1 z10
z 2 z_2 z20
z 3 z_3 z31
z 4 z_4 z42
z 5 z_5 z55
z 6 z_6 z66
z 7 z_7 z77

第三步,找到 z q z_q zq最小值。所以值 G ( Z q ) G(Z_q) G(Zq)最接近 s k s_k sk。我们对每一个 s k s_k sk值这样做,以产生从s到z所需要的映射。

  • s 0 = 1 s_0=1 s0=1,我们看到 G ( z 3 ) = 1 G(z_3)=1 G(z3)=1,在这种情况下,这是最完美的匹配,因此有对应 s 0 = > z 3 s_0=>z_3 s0=>z3。也就是说,直方图均衡后的图像中的每一个值为1的像素映射为直方图规定化后的图像中(相应位置上)的值为3的像素。
  • s 1 = 3 s_1=3 s1=3, G ( z q ) G(z_q) G(zq)中不存在对应的3,则找最接近3的值,则为2或者4。则有 s 1 = > z 4 s_1=>z_4 s1=>z4.
  • s 2 = 5 s_2=5 s2=5, G ( z 5 ) = 5 G(z_5)=5 G(z5)=5与之完美对应,则有 s 2 = > z 5 s_2=>z_5 s2=>z5.
  • s 3 = 6 s_3=6 s3=6, G ( z 6 ) = 6 G(z_6)=6 G(z6)=6与之完美对应,则有 s 3 = > z 6 s_3=>z_6 s3=>z6.

由此可以得到映射关系:

表3.4
s k s_k sk—> z q z_q zq
1—>3
3 3 3—>4
5 5 5—>5
6 6 6—>6
7 7 7—>7

结合3.11和3.4中的映射把直方图均衡后的图像中的每个像素映射为新创建的直方图规定化图像中相应的像素。结果如下:

z q z_q zq规定的 p z ( Z q ) p_z(Z_q) pz(Zq)实际的 p z ( z k ) p_z(z_k) pz(zk)
z 0 = 0 z_0=0 z0=00.000.00
z 1 = 1 z_1=1 z1=10.000.00
z 2 = 2 z_2=2 z2=20.000.00
z 3 = 3 z_3=3 z3=30.150.19
z 4 = 4 z_4=4 z4=40.200.25
z 5 = 5 z_5=5 z5=50.300.21
z 6 = 6 z_6=6 z6=60.200.24
z 7 = 7 z_7=7 z7=70.150.11

在这里插入图片描述在这里插入图片描述

代码实现

直方图规定化中要注意两点:


实际操作中不会进行两次均衡化。在推导中发现,假如sk 规定化后的对应灰度是zm的话,需要满足的条件是sk的累积概率和zm的累积概率是最接近的。所以可以根据计算累计密度的差值来进行映射。

	//1.传入原图和待处理的目标图
	Mat src1, src2;
	src1 = imread("D:/test/src1.jpg");
	src2 = imread("D:/test/src2.jpg");

	//2. 将原图和目标图转化为灰度图像
	Mat graySrc1, graySrc2;
	cvtColor(src1, graySrc1, COLOR_BGR2GRAY);
	cvtColor(src2, graySrc2, COLOR_RGB2GRAY);

	//3. 将图像进行均衡化处理
	equalizeHist(graySrc1, graySrc1);
	equalizeHist(graySrc2, graySrc2);

	//4. 计算图像的直方图
	/*
	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 );
	*/
	int channels = 0;
	Mat dst(src2.cols, src2.rows, CV_8UC3);
	//计算均衡化后的图像的直方图
	int dims = 1;
	int histSize = 256;
	float range[] = { 0,255 };
	const float *histRange[] = { range };
	Mat src1Hist, src2Hist;
	calcHist(&graySrc1, 1, &channels, Mat(), src1Hist, dims, &histSize, histRange);
	calcHist(&graySrc2, 1, &channels, Mat(), src2Hist, dims, &histSize, histRange);

	//计算图像的累计直方图
	float src1_cdf[256] = { 0 };
	float src2_cdf[256] = { 0 };
	for (int i = 0; i < 256; i++) {
		if (i == 0) {
			src1_cdf[i] = src1Hist.at<float>(i);
			src2_cdf[i] = src2Hist.at<float>(i);
		}
		else
		{
			src1_cdf[i] = src1_cdf[i - 1] + src1Hist.at<float>(i);
			src2_cdf[i] = src2_cdf[i - 1] + src2Hist.at<float>(i);
		}
	}

	//对图像目标进行规定化处理
	// 1. 计算累计概率的差值
	float diff_cdf[256][256];
	for (int i = 0;i < 256;i++) {
		for (int j = 0; j < 256; j++)
		{
			diff_cdf[i][j] = fabs(src1_cdf[i] - src2_cdf[j]);
		}
	}
	//2. 构建灰度级映射表
	Mat lut(1, 256, CV_8U);
	for (int i = 0; i < 256; i++)
	{
		//查找源灰度级为i的映射灰度和i的累积概率差最小的规定化灰度
		float min = diff_cdf[i][0];
		int index = 0;
		for (int j = 0; j < 256; j++) {
			if (min > diff_cdf[i][j]) {
				min = diff_cdf[i][j];
				index = j;
			}
		}
		lut.at<uchar>(i) = static_cast<uchar>(index);
	}
	LUT(graySrc2, lut, dst);

	waitKey(0);
	return 0;

学习:
OpenCV 直方图处理:直方图均衡和规定化(匹配)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值