实现均值滤波和中值滤波,结合直方图均衡化分析效果

一、实验目的

在之前实现的BMP图像解析和直方图均衡化的基础上,本次实验将进一步扩展功能,实现均值滤波(Mean Filter)和中值滤波(Median Filter)两种常见的图像平滑算法。通过这些算法的应用,我们将观察它们对图像噪声和细节的影响,并与直方图均衡化的效果进行对比分析。实验过程中,我们依然不依赖任何第三方图像处理库,完全依靠标准C++和BMP文件格式规范自行编写代码。

二、实验环境

开发工具:Visual Studio 2022

编程语言:C++

操作系统:Windows 11

图像格式:BMP(24位RGB)

三、实验步骤

1. BMP 文件解析和直方图均衡化

这部分内容已经在之前的实验中实现,这里不再赘述。请参考之前的实验报告中的相关部分。

链接:基于C++的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文件格式规范自行编写代码。这不仅加深了我们对图像处理算法的理解,也提高了我们的编程能力和问题解决能力。

 

作者:星尘旅人
1.本网站部分素材来源于网络,仅供大家参考学习,如有侵权,请联系博主删除处理。
2.本网站一切内容不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
3.版权&许可请详阅版权声明
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
//音乐播放