0%

图像信息处理Assignment5

第五次图像信息处理作业,大致上就是图像的模糊和锐化吧。

Assignment-5作业要求

  • Image mean filtering
  • Laplacian image enhancement

作业分析

均值滤波

其实由上次作业可以知道,图像的处理就是由一系列矩阵变换得到的结果,不过在这次作业中,我们选择的是对像素进行矩阵变换而不是像素坐标,而均值滤波,顾名思义,就是对图像像素取均值得到新的像素值,以$3\times3$矩阵为例,其变换矩阵如下

值得注意的是,对于边缘的像素值,我们在这里对其进行保留处理。由此我们可以很快的写出代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
uint8_t* imgMean(const uint8_t* imgData, int bitCount, int height, int width) {
int lineBytes = (bitCount * width / 8 + 3) / 4 * 4;
uint8_t* meanData = new uint8_t[lineBytes * height]{};
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (i == 0 || i == height - 1 || j == 0 || j == width - 1) {
*(meanData + i * lineBytes + j * 3) = *(imgData + i * lineBytes + j * 3);
*(meanData + i * lineBytes + j * 3 + 1) = *(imgData + i * lineBytes + j * 3 + 1);
*(meanData + i * lineBytes + j * 3 + 2) = *(imgData + i * lineBytes + j * 3 + 2);
}
else {
int r = *(imgData + i * lineBytes + j * 3) + *(imgData + (i + 1) * lineBytes + j * 3) + *(imgData + (i - 1) * lineBytes + j * 3) +
*(imgData + i * lineBytes + (j - 1) * 3) + *(imgData + i * lineBytes + (j + 1) * 3) + *(imgData + (i - 1) * lineBytes + (j - 1) * 3) +
*(imgData + (i - 1) * lineBytes + (j + 1) * 3) + *(imgData + (i + 1) * lineBytes + (j - 1) * 3) + *(imgData + (i + 1) * lineBytes + (j + 1) * 3);
int g = *(imgData + i * lineBytes + j * 3 + 1) + *(imgData + (i + 1) * lineBytes + j * 3 + 1) + *(imgData + (i - 1) * lineBytes + j * 3 + 1) +
*(imgData + i * lineBytes + (j - 1) * 3 + 1) + *(imgData + i * lineBytes + (j + 1) * 3 + 1) + *(imgData + (i - 1) * lineBytes + (j - 1) * 3 + 1) +
*(imgData + (i - 1) * lineBytes + (j + 1) * 3 + 1) + *(imgData + (i + 1) * lineBytes + (j - 1) * 3 + 1) + *(imgData + (i + 1) * lineBytes + (j + 1) * 3 + 1);
int b = *(imgData + i * lineBytes + j * 3 + 2) + *(imgData + (i + 1) * lineBytes + j * 3 + 2) + *(imgData + (i - 1) * lineBytes + j * 3 + 2) +
*(imgData + i * lineBytes + (j - 1) * 3 + 2) + *(imgData + i * lineBytes + (j + 1) * 3 + 2) + *(imgData + (i - 1) * lineBytes + (j - 1) * 3 + 2) +
*(imgData + (i - 1) * lineBytes + (j + 1) * 3 + 2) + *(imgData + (i + 1) * lineBytes + (j - 1) * 3 + 2) + *(imgData + (i + 1) * lineBytes + (j + 1) * 3 + 2);
*(meanData + i * lineBytes + j * 3) = (uint8_t)(r / 9);
*(meanData + i * lineBytes + j * 3 + 1) = (uint8_t)(g / 9);
*(meanData + i * lineBytes + j * 3 + 2) = (uint8_t)(b / 9);
}
}
}
return meanData;
}

最终结果对比

当然我们也可以修改均值滤波的矩阵,例如改成如下

那么这样图像的亮度也会有些许变化

拉普拉斯图像增强

这里我们使用拉普拉斯算子进行图像的增强,其中我们需要先计算出拉普拉斯遮罩

然后我们将原像素减去拉普拉斯遮罩即可得出锐化之后的图像,当然这里需要注意增强后的图像溢色的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
uint8_t* imgLaplacian(const uint8_t* imgData, int bitCount, int height, int width) {
int lineBytes = (bitCount * width / 8 + 3) / 4 * 4;
uint8_t* lapData = new uint8_t[lineBytes * height]{};
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (i == 0 || i == height - 1 || j == 0 || j == width - 1) {
*(lapData + i * lineBytes + j * 3) = *(imgData + i * lineBytes + j * 3);
*(lapData + i * lineBytes + j * 3 + 1) = *(imgData + i * lineBytes + j * 3 + 1);
*(lapData + i * lineBytes + j * 3 + 2) = *(imgData + i * lineBytes + j * 3 + 2);
}
else {
int r = 8 * *(imgData + i * lineBytes + j * 3) - *(imgData + (i + 1) * lineBytes + j * 3) - *(imgData + (i - 1) * lineBytes + j * 3) -
*(imgData + i * lineBytes + (j - 1) * 3) - *(imgData + i * lineBytes + (j + 1) * 3) - *(imgData + (i - 1) * lineBytes + (j - 1) * 3) -
*(imgData + (i - 1) * lineBytes + (j + 1) * 3) - *(imgData + (i + 1) * lineBytes + (j - 1) * 3) - *(imgData + (i + 1) * lineBytes + (j + 1) * 3);
int g = 8 * *(imgData + i * lineBytes + j * 3 + 1) - *(imgData + (i + 1) * lineBytes + j * 3 + 1) - *(imgData + (i - 1) * lineBytes + j * 3 + 1) -
*(imgData + i * lineBytes + (j - 1) * 3 + 1) - *(imgData + i * lineBytes + (j + 1) * 3 + 1) - *(imgData + (i - 1) * lineBytes + (j - 1) * 3 + 1) -
*(imgData + (i - 1) * lineBytes + (j + 1) * 3 + 1) - *(imgData + (i + 1) * lineBytes + (j - 1) * 3 + 1) - *(imgData + (i + 1) * lineBytes + (j + 1) * 3 + 1);
int b = 8 * *(imgData + i * lineBytes + j * 3 + 2) - *(imgData + (i + 1) * lineBytes + j * 3 + 2) - *(imgData + (i - 1) * lineBytes + j * 3 + 2) -
*(imgData + i * lineBytes + (j - 1) * 3 + 2) - *(imgData + i * lineBytes + (j + 1) * 3 + 2) - *(imgData + (i - 1) * lineBytes + (j - 1) * 3 + 2) -
*(imgData + (i - 1) * lineBytes + (j + 1) * 3 + 2) - *(imgData + (i + 1) * lineBytes + (j - 1) * 3 + 2) - *(imgData + (i + 1) * lineBytes + (j + 1) * 3 + 2);
r += *(imgData + i * lineBytes + j * 3);
g += *(imgData + i * lineBytes + j * 3 + 1);
b += *(imgData + i * lineBytes + j * 3 + 2);
r = r > 255 ? 255 : r;
g = g > 255 ? 255 : g;
b = b > 255 ? 255 : b;
r = r < 0 ? 0 : r;
g = g < 0 ? 0 : g;
b = b < 0 ? 0 : b;
*(lapData + i * lineBytes + j * 3) = r;
*(lapData + i * lineBytes + j * 3 + 1) = g;
*(lapData + i * lineBytes + j * 3 + 2) = b;
}
}
}
return lapData;
}

最终结果如下

总结

这次作业确实还蛮简单的,最后总计的编程时间可能一个小时都不到,不过这些矩阵运算还是十分重要的

同时长远地想,配合别的不同的滤波器可以实现其他不同的效果,可以算是图像滤波的入门体验作业吧