一、实验目的
在之前实现的BMP图像解析和直方图均衡化的基础上,本次实验将进一步扩展功能,实现均值滤波(Mean Filter)和中值滤波(Median Filter)两种常见的图像平滑算法。通过这些算法的应用,我们将观察它们对图像噪声和细节的影响,并与直方图均衡化的效果进行对比分析。实验过程中,我们依然不依赖任何第三方图像处理库,完全依靠标准C++和BMP文件格式规范自行编写代码。
二、实验环境
开发工具:Visual Studio 2022
编程语言:C++
操作系统:Windows 11
图像格式:BMP(24位RGB)
三、实验步骤
1. BMP 文件解析和直方图均衡化
这部分内容已经在之前的实验中实现,这里不再赘述。请参考之前的实验报告中的相关部分。
2. 均值滤波(Mean Filter)实现
均值滤波是一种简单的线性滤波器,它通过计算邻域内像素的平均值来平滑图像,从而减少噪声。以下是均值滤波的实现代码:
void ApplyMeanFilter(std::vector<uint8_t>& image, int width, int height, int kernelSize) { if (kernelSize % 2 == 0 || kernelSize < 3) { std::cerr << "Kernel size must be an odd number greater than or equal to 3." << std::endl; return; } int halfKernel = kernelSize / 2; std::vector<uint8_t> tempImage = image; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { for (int c = 0; c < 3; ++c) { // RGB channels int sum = 0; int count = 0; for (int ky = -halfKernel; ky <= halfKernel; ++ky) { for (int kx = -halfKernel; kx <= halfKernel; ++kx) { int nx = std::max(0, std::min(width - 1, x + kx)); int ny = std::max(0, std::min(height - 1, y + ky)); sum += tempImage[(ny * width + nx) * 3 + c]; count++; } } image[(y * width + x) * 3 + c] = static_cast<uint8_t>(sum / count); } } } }
3. 中值滤波(Median Filter)实现
中值滤波是一种非线性滤波器,它通过选择邻域内像素的中值来平滑图像,特别适合去除椒盐噪声。以下是中值滤波的实现代码:
void ApplyMedianFilter(std::vector& image, int width, int height, int kernelSize) { if (kernelSize % 2 == 0 || kernelSize < 3) { std::cerr << "Kernel size must be an odd number greater than or equal to 3." << std::endl; return; } int halfKernel = kernelSize / 2; std::vector tempImage = image; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { for (int c = 0; c < 3; ++c) { // RGB channels std::vector window; for (int ky = -halfKernel; ky <= halfKernel; ++ky) { for (int kx = -halfKernel; kx <= halfKernel; ++kx) { int nx = std::max(0, std::min(width - 1, x + kx)); int ny = std::max(0, std::min(height - 1, y + ky)); window.push_back(tempImage[(ny * width + nx) * 3 + c]); } } std::nth_element(window.begin(), window.begin() + window.size() / 2, window.end()); image[(y * width + x) * 3 + c] = static_cast(window[window.size() / 2]); } } } }
4. 结合直方图均衡化
为了更全面地评估滤波效果,我们可以在应用滤波后进行直方图均衡化处理。这样可以观察滤波对图像噪声和细节的影响,以及后续均衡化对图像对比度的提升。
void ProcessImageWithFiltersAndHistogramEqualization(const std::string& inputFilename, const std::string& outputFilename, int kernelSize, bool useMeanFilter) { std::vector imageBuffer; int width = 0, height = 0; if (!LoadBitmap(inputFilename, imageBuffer, width, height)) { std::cerr << "Failed to load bitmap file." << std::endl; return; } std::cout << "Loaded image: " << width << "x" << height << std::endl; // 创建一个副本用于滤波和直方图均衡化 std::vector processedImage = imageBuffer; // 应用滤波 if (useMeanFilter) { ApplyMeanFilter(processedImage, width, height, kernelSize); std::cout << "Mean filter applied with kernel size " << kernelSize << "." << std::endl; } else { ApplyMedianFilter(processedImage, width, height, kernelSize); std::cout << "Median filter applied with kernel size " << kernelSize << "." << std::endl; } // 应用直方图均衡化 ApplyHistogramEqualization(processedImage, width, height); std::cout << "Histogram equalization applied." << std::endl; // 保存处理后的图像 if (SaveBitmap(outputFilename, processedImage, width, height)) { std::cout << "Saved processed image to " << outputFilename << std::endl; } else { std::cerr << "Failed to save the processed image." << std::endl; } }
5. 主程序
在主程序中,我们可以调用ProcessImageWithFiltersAndHistogramEqualization函数,分别测试均值滤波和中值滤波的效果。
int main() { std::string inputFilename = "path_to_your_bmp_file.bmp"; // 替换为实际路径 int kernelSize = 3; // 滤波器核大小 // 测试均值滤波 std::string meanOutputFilename = "output_mean_hist_eq.bmp"; ProcessImageWithFiltersAndHistogramEqualization(inputFilename, meanOutputFilename, kernelSize, true); // 测试中值滤波 std::string medianOutputFilename = "output_median_hist_eq.bmp"; ProcessImageWithFiltersAndHistogramEqualization(inputFilename, medianOutputFilename, kernelSize, false); return 0; }
四、实验结果与分析
1. 结果展示
我们选择了几张不同类型的BMP图像进行测试,并将处理前后的图像进行了对比。以下是部分测试结果:
原图:
均值滤波 + 直方图均衡化:
中值滤波 + 直方图均衡化:
2. 效果分析
通过对多张图像的测试,我们可以观察到均值滤波和中值滤波对图像噪声和细节的不同影响,以及直方图均衡化对图像对比度的提升。具体表现在以下几个方面:
噪声抑制:
均值滤波:均值滤波能够有效平滑图像,减少随机噪声。然而,它也会模糊图像的边缘和细节,特别是在较大核尺寸的情况下。
中值滤波:中值滤波在去除椒盐噪声方面表现尤为出色,同时保留了更多的图像细节。相比均值滤波,中值滤波对边缘的保护更好,但处理时间较长。
细节保留:
均值滤波:由于其线性特性,均值滤波会均匀地模糊图像,导致一些细小的纹理和边缘信息丢失。
中值滤波:中值滤波是非线性的,因此能够在去除噪声的同时较好地保留图像的细节和边缘。
对比度增强:
直方图均衡化:无论是在原始图像还是经过滤波处理的图像上,直方图均衡化都能显著增强图像的对比度,使暗部和亮部细节更加清晰。结合滤波处理,直方图均衡化可以进一步提升图像的整体视觉效果。
综合效果:
均值滤波 + 直方图均衡化:适用于需要平滑图像并增强对比度的场景,但在处理含有重要细节的图像时,可能会损失一些细节信息。
中值滤波 + 直方图均衡化:适用于含有椒盐噪声的图像,能够在去噪的同时较好地保留图像细节,尤其适合处理自然风景或复杂纹理的图像。
五、结论
通过本次实验,我们成功实现了均值滤波和中值滤波两种常见的图像平滑算法,并结合直方图均衡化对图像进行了处理。实验结果显示,这两种滤波器在噪声抑制和细节保留方面各有优劣,而直方图均衡化能够显著增强图像的对比度,改善视觉效果。
此外,实验过程中我们严格遵守了不使用任何第三方图像处理库的要求,完全依靠标准C++和BMP文件格式规范自行编写代码。这不仅加深了我们对图像处理算法的理解,也提高了我们的编程能力和问题解决能力。