问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

均值滤波器的原理及实现

创作时间:
作者:
@小白创作中心

均值滤波器的原理及实现

引用
CSDN
1.
https://blog.csdn.net/u013263891/article/details/83048641

均值滤波器是图像处理中一种常用的线性空间滤波器,主要用于降低图像噪声和去除不相关细节。本文将详细介绍均值滤波器的原理,并通过C++和OpenCV实现其功能,最后展示不同处理方式的效果对比。

1. 均值滤波器原理

平滑线性空间滤波器的输出是包含在滤波器模板邻域内的像素的简单平均值,也就是均值滤波器。均值滤波器也是低通滤波器,其主要作用是将邻域内的平均值赋给中心元素。

均值滤波器的主要应用包括:

  • 降低噪声
  • 去除图像中的不相关细节
  • 模糊图片以便得到感兴趣物体的粗略描述

模板的大小由那些即将融入背景中的物体尺寸决定。然而,均值滤波器也存在边缘模糊的缺点。

均值滤波器的模板可以分为标准像素平均和加权平均两种类型。

2. C++实现均值滤波器

下面通过C++和OpenCV实现均值滤波器:

#include <iostream>
#include<opencv2/opencv.hpp>

// 计算标准均值滤波器的权重
void getCount(double *count, int dim) {
    int mn = dim * dim;
    for (int i = 0; i < dim * dim; i++) {
        count[i] = 1.0 / mn;
    }
}

// 计算加权均值滤波器的权重
void getCountWeight(double *count, int dim) {
    int mn = dim * dim;
    for (int i = 0; i < mn; i++) {
        if (i == mn / 2)
            count[i] = 1. / 2;
        else
            count[i] = (1 / 2.) * (1. / (mn - 1));
    }
}

// 均值滤波器函数
void meanFilter(cv::Mat &dst, cv::Mat &img, int dim) {
    int channels = img.channels();
    dst = cv::Mat::zeros(img.size(), img.type());
    double count[dim * dim] = {0};
    getCountWeight(count, dim);
    for (int row = 0; row < img.rows; row++) {
        for (int col = 0; col < img.cols; col++) {
            if (row >= dim / 2 && row < img.rows - dim / 2 && col >= dim / 2 && col < img.cols - dim / 2) {
                int c = 0;
                double sum1 = 0;
                double sum2 = 0;
                double sum3 = 0;
                for (int i = row - dim / 2; i <= row + dim / 2; i++) {
                    for (int j = col - dim / 2; j <= col + dim / 2; j++) {
                        if (channels == 1) {
                            sum1 += count[c] * img.at<uchar>(i, j);
                        } else if (channels == 3) {
                            sum1 += count[c] * img.at<cv::Vec3b>(i, j)[0];
                            sum2 += count[c] * img.at<cv::Vec3b>(i, j)[1];
                            sum3 += count[c] * img.at<cv::Vec3b>(i, j)[2];
                        }
                        c++;
                    }
                }
                if (channels == 1) {
                    dst.at<uchar>(row, col) = (int)sum1;
                } else if (channels == 3) {
                    dst.at<cv::Vec3b>(row, col)[0] = (int)sum1;
                    dst.at<cv::Vec3b>(row, col)[1] = (int)sum2;
                    dst.at<cv::Vec3b>(row, col)[2] = (int)sum3;
                }
            } else {
                if (channels == 1)
                    dst.at<uchar>(row, col) = img.at<uchar>(row, col);
                else if (channels == 3) {
                    dst.at<cv::Vec3b>(row, col)[0] = img.at<cv::Vec3b>(row, col)[0];
                    dst.at<cv::Vec3b>(row, col)[1] = img.at<cv::Vec3b>(row, col)[1];
                    dst.at<cv::Vec3b>(row, col)[2] = img.at<cv::Vec3b>(row, col)[2];
                }
            }
        }
    }
}

int main() {
    cv::Mat src = cv::imread("/home/dyf/Documents/数字图像/空间滤波器/Mean-filter/3.png", 0);
    cv::Mat dst, dst1;
    cv::imshow("src", src);
    meanFilter(dst, src, 3);
    cv::imshow("dst", dst);
    cv::blur(src, dst1, cv::Size(3, 3));
    cv::imshow("dst1", dst1);
    cv::waitKey(0);
    return 0;
}

3. 均值滤波器处理效果

以下是使用不同方法处理的效果对比:


原图像


左侧为带权重均值处理结果(中心位置为0.5,其他的邻域平分0.5) 右侧为标准均值处理结果


左侧为带权重均值处理结果(中心位置为0.5,其他的邻域平分0.5) 右侧为标准均值处理结果


左侧为带权重均值处理结果(中心位置为0.5,其他的邻域平分0.5) 右侧为标准均值处理结果


左侧为带权重均值处理结果(中心位置为0.5,其他的邻域平分0.5) 右侧为标准均值处理结果

从效果对比可以看出:

  • 标准均值滤波器对图像进行了均匀的模糊处理
  • 带权重的均值滤波器在保持中心像素的同时对周围像素进行模糊,能够更好地保留图像细节

总结

均值滤波器是一种简单而有效的图像降噪和细节去除工具。虽然它能够很好地降低噪声,但也会导致边缘模糊。在实际应用中,需要根据具体需求选择合适的滤波器类型和参数。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号