数字图像处理 || 拉普拉斯算子锐化滤波&&标定差度方法

  • c++ CImg
  • 采用标定和为标定两种实现算法

未标定:

CImg<int> laplace_filter(CImg<int> img) {
	MatrixXd m(3, 3);
	for(int x = 0;x < 3; x++) {
		for (int y = 0; y < 3; y++) {
			if (x == 1 && y == 1) {
				m(x, y) = 8;
			}
			else
				m(x, y) = -1;
		}
	}
	int x = 0, y = 0;
	int w = img.width(), h = img.height();
	CImg<int> pic(w, h, 1, 1);
	pic = img;
	pic.resize(w + 2 , h + 2 , 1, 1);
	CImg<int> pic1 = pic;
		CImg<int> temp(w,h,1,1);
		cimg_forXY(pic, x, y) {
			if (x >= 1 && y >= 1 && x <= w  && y <= h ) {
				CImg<int> t(3, 3);
				for (int i = 0; i < 3; i++) {
					for (int j = 0; j < 3; j++) {
						t(i, j) = pic1(x-1+i, y-1+j);
					}
				}
				int sum = 0;
				cimg_forXY(t, i1, j1) {
					for (int i2 = 0; i2 < 3; i2++) {
						for (int j2 = 0; j2 < 3; j2++) {
							if (i1 + i2 == 2 && j1 + j2 == 2) {
								sum += t(i1, j1)*m(i2, j2);
							}
						}
					}
				}
				if (sum < 0)sum = 0;
				else if (sum > 255) sum = 255;
				else sum = sum;
				pic(x, y) = sum;
			}
		}
	return pic;
}

标定:

CImg<int> laplace_filterbiaoding(CImg<int> img) {
	MatrixXd m(3, 3);
	for (int x = 0; x < 3; x++) {
		for (int y = 0; y < 3; y++) {
			if (x == 1 && y == 1) {
				m(x, y) = 8;
			}
			else
				m(x, y) = -1;
		}
	}
	int x = 0, y = 0;
	int w = img.width(), h = img.height();
	CImg<int> pic(w, h, 1, 1);
	pic = img;
	pic.resize(w + 2, h + 2, 1, 1);
	CImg<int> pic1 = pic;
	CImg<int> temp(w, h, 1, 1);
	int min = 100000;
	cimg_forXY(pic, x, y) {
		if (x >= 1 && y >= 1 && x <= w && y <= h) {
			CImg<int> t(3, 3);
			for (int i = 0; i < 3; i++) {
				for (int j = 0; j < 3; j++) {
					t(i, j) = pic1(x - 1 + i, y - 1 + j);
				}
			}
			int sum = 0;
			cimg_forXY(t, i1, j1) {
				for (int i2 = 0; i2 < 3; i2++) {
					for (int j2 = 0; j2 < 3; j2++) {
						if (i1 + i2 == 2 && j1 + j2 == 2) {
							sum += t(i1, j1)*m(i2, j2);
							if (sum < min) min = sum;
						}
					}
				}
			}
			pic(x, y) = sum;
		}
	}
	cimg_forXY(pic, x, y) {
		//cout << pic(x, y) <<" ";
		pic(x, y) -= min;
	}
	int max = -1;
	cimg_forXY(pic, x, y) {
		if (pic(x, y) > max)
			max = pic(x, y);
	}
	cimg_forXY(pic, x, y) {
		pic(x, y) = pic(x, y) * 255 / max;
	}
	return pic;
}

这里顺便说一下常用的标定方法有两种:

  • 方法一:
    对每一个像素值再加上255,然后除以2。该方法无法保证像素的取值可以覆盖0到255的全部8比特范围,但是所有的像素一定在这一范围。另外,在除以2过程中固有的截尾误差通常将导致精确度的损失。虽然有很多的不足,但是该非常的简单方便。

  • 方法二:
    该方法弥补的方法一的缺点,它可以得到更高的精确度并使像素取值覆盖整个8比特的范围。我们首先提取最小值,并把它的负值加到所有的差值图像的像素中(如果最小值是-a(a>0),则加上a;如果最小值是a,则减去a;通过该操作后,差值图像中最小的值就为0了)。之后,每一个像素乘以255/Max,其中Max为上一步操作之后图像的中最大像素值,这样就将所有的像素标定到0到255的范围内。

运行结果:

未标定

在这里插入图片描述
原图:
在这里插入图片描述
与原图加到一起后处理的效果:
在这里插入图片描述

效果是不是特别棒棒!!!

猜你喜欢

转载自blog.csdn.net/perry0528/article/details/82895128