- 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的范围内。
运行结果:
原图:
与原图加到一起后处理的效果:
效果是不是特别棒棒!!!