第五次图像信息处理作业,大致上就是图像的模糊和锐化吧。
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; }
|
最终结果如下
总结
这次作业确实还蛮简单的,最后总计的编程时间可能一个小时都不到,不过这些矩阵运算还是十分重要的
同时长远地想,配合别的不同的滤波器可以实现其他不同的效果,可以算是图像滤波的入门体验作业吧