锐化处理:锐化处理的主要目的是突出图像中的细节或增强被模糊的细节。锐化处理所讨论的重点是微分性质,恒定灰度区域、突出的开头与结尾,沿着灰度级斜坡处的特性。

一阶微分:

af/ax = f(x+1)-f(x)

二阶微分:

a2f/a2x = f(x+1)+f(x-1)-2f(x)

两种不同方式对于锐化处理的影响:

1、沿着整个斜坡,一阶微分都不为零,而二阶微分后,非零值只出现在斜坡的起点和终点,所以说,一阶微分会产生较粗的边缘,而二阶微分则细很多。

2、二阶微分处理对细节有较强的相应,如细线和孤立点等。

3、二阶微分处理对灰度级阶梯变化会出现双响应,一个是斜坡开始时为正响应,一个为斜坡结束时为负响应。

拉普拉斯算子的由来:

根据以上的二阶微分公式,将点(x,y)带入以上公式中就可以得到一个在90度方向旋转上各向同性的拉普拉斯算子:

0  1    0                                                                                                                   1       1        1

1  -4   1     为了使旋转更加多元可以将四个角上的点也加入进来实现45度旋转同性: 1       -8       1

0   1   0                                                                                                                    1        1       1

拉普拉斯的应用强调图像中的灰度的突变以及降低灰度慢变化的区域。

一阶算子:

由于拉普拉斯为二阶算子,那么一阶算子可以根据一阶微分公式得来,不一样的地方在于,Robert提出了交叉差分的算法。这就是Roberts算子的由来其意思为:

ax = Z1 – Z4  ay = Z2 – Z3

即:

(0   1        (1  0

   -1   0)      0    -1) 

与平滑部分一样,由于偶数个数的算子并不好用,则使用三阶算子这就是Prewitt算子:

(-1     -1      -1           (1      0      -1

   0        0        0             1       0       -1

   1          1        1)        1       0       -1)

由于图像需要突出中心点,增加图像的丰富程度,可以给图像不同的权值,这也就是非常常用的Soble算子:

(-1     -2      -1           (1      0      -1

   0        0        0              2      0       -2

   1        2        1)          1       0       -1)

void ruihuaBianHuan::sobel()
{
	BYTE* p_data = getData();
	int width = getWidth();
	int height = getHeight();
	BYTE* temp1 = new BYTE[width*height];
	memcpy(temp1, p_data, width*height);
	BYTE* temp2 = new BYTE[width*height];
	memcpy(temp2, p_data, width*height);
	int tempMX, tempMY, tempH, tempW;
	float tempC;
	float templat[9];
	tempW = 3; tempH = 3; tempMX = 1; tempMY = 1; tempC = 1.0;//tempC为模板系数其大小主要控制亮度因为在模板运算完后才乘上tempC增大整个模板的值使总体亮度增加
	templat[0] = -1.0; templat[1] = -2.0; templat[2] = -1.0; templat[3] = 0.0; templat[4] = 0.0; templat[5] = 0.0;
	templat[6] = 1.0; templat[7] = 2.0; templat[8] = 1.0;
	this->templat(temp1, width, height, tempH, tempW, tempMX, tempMY, templat, tempC);
	templat[0] = -1.0; templat[1] = 0.0; templat[2] = 1.0; templat[3] = -2.0; templat[4] = 0.0; templat[5] = 2.0;
	templat[6] = -1.0; templat[7] = 0.0; templat[8] = 1.0;
	this->templat(temp2, width, height, tempH, tempW, tempMX, tempMY, templat, tempC);
	for(int j=0;j<height;j++)
		for (int i = 0; i < width; i++)
		{
			if (temp1[j*width + i] < temp2[j*width + i])
				temp1[j*width + i] = temp2[j*width + i];
		}
	memcpy(p_data, temp1, width*height);
	delete temp1;
	delete temp2;
}


版权声明:本文为qq_27591163原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_27591163/article/details/79600787