博客
关于我
均值滤波原理及C++实现
阅读量:798 次
发布时间:2023-04-15

本文共 2537 字,大约阅读时间需要 8 分钟。

均值滤波:原理与实现

写在前面

从均值滤波开始,着手实现各种常用的滤波算法。均值滤波是一种线性滤波。图像的空域滤波无非分为两种,线性滤波和非线性滤波。由于我之前对线性、非线性理解不够清晰,这次就好好总结一下吧。


线性滤波

线性滤波对邻域中的像素的计算为线性运算时,如利用窗口函数进行平滑加权求和的运算,或者某种卷积运算,都可以称为线性滤波。常见的线性滤波有:均值滤波、高斯滤波、盒子滤波、拉普拉斯滤波等等,通常线性滤波器之间只是模版系数不同。


非线性滤波

非线性滤波利用原始图像跟模版之间的一种逻辑关系得到结果,如最值滤波器,中值滤波器。比较常用的有中值滤波器和双边滤波器。


均值滤波的应用场合

根据冈萨雷斯书中的描述,均值模糊可以模糊图像以便得到感兴趣物体的粗略描述,也就是说,去除图像中的不相关细节,其中“不相关”是指与滤波器模板尺寸相比较小的像素区域,从而对图像有一个整体的认知。即为了对感兴趣的物体得到一个大致的整体的描述而模糊一幅图像,忽略细小的细节。


均值滤波的缺陷

均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。特别是椒盐噪声。


原理

均值滤波的原理很简单,一般是用下面的系数模版与图像做卷积运算,公式表示为:

$$g(x,y) = \frac{1}{n} \sum_{(x',y') \in D} f(x',y')$$

其中 (D) 是一个 (k \times k) 的邻域,(n) 是邻域中像素的数量,(g(x,y)) 是滤波后的像素值,(f(x',y')) 是原图像对应位置的像素值。

常见的模板大小有 (3 \times 3)、(5 \times 5)、(7 \times 7) 等,图像边界可以通过扩充处理(如扩充为0或邻近像素值)。


结果分析

如果采用常规方法,随着模板尺寸的增大,求和计算量也急剧增大,而且模板是逐像素移动的,可见这种效率上的代价是巨大的。下一篇将介绍一种采用积分图处理的快速均值滤波方法,会大大提高执行效率,可以说是工程应用的首选!


代码(常规方法)

#include 
#include
#include
#include
void MeanFilter(cv::Mat& src, cv::Mat& dst, cv::Size wsize) { int hh = (wsize.height - 1) / 2; int hw = (wsize.width - 1) / 2; cv::Mat newsrc; cv::copyMakeBorder(src, newsrc, hh, hh, hw, hw, cv::BORDER_REFLECT_101); dst = cv::Mat::zeros(src.size(), src.type()); int sum = 0; int mean = 0; for (int i = hh; i < src.rows + hh; ++i) { for (int j = hw; j < src.cols + hw; ++j) { for (int r = i - hh; r <= i + hh; ++r) { for (int c = j - hw; c <= j + hw; ++c) { sum = newsrc.at
(r, c) + sum; } } mean = sum / wsize.area(); dst.at
(i - hh, j - hw) = mean; sum = 0; mean = 0; } }}int main() { cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\Fig0334(a)(hubble-original).tif"); if (src.empty()) { return -1; } if (src.channels() > 1) { cv::cvtColor(src, src, CV_RGB2GRAY); } cv::Mat dst; cv::Mat dst1; cv::Size wsize(7, 7); double t2 = (double)cv::getTickCount(); MeanFilter(src, dst, wsize); t2 = (double)cv::getTickCount() - t2; double time2 = (t2 * 1000.) / ((double)cv::getTickFrequency()); std::cout << "FASTmy_process=" << time2 << " ms. " << std::endl << std::endl; cv::namedWindow("src"); cv::imshow("src", src); cv::namedWindow("dst"); cv::imshow("dst", dst); cv::imwrite("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Image Filtering\\MeanFilter\\Mean_hubble.jpg", dst); cv::waitKey(0);}

以上代码实现了常规均值滤波算法,通过对图像边界扩充和卷积操作实现均值滤波效果。

转载地址:http://rrrfk.baihongyu.com/

你可能感兴趣的文章
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>
MySQL 存储过程参数:in、out、inout
查看>>
mysql 存储过程每隔一段时间执行一次
查看>>
mysql 存在update不存在insert
查看>>
Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
查看>>
Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
查看>>
Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
查看>>
Mysql 学习总结(89)—— Mysql 库表容量统计
查看>>
mysql 实现主从复制/主从同步
查看>>
mysql 审核_审核MySQL数据库上的登录
查看>>
mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
查看>>
mysql 导入导出大文件
查看>>
MySQL 导出数据
查看>>
mysql 将null转代为0
查看>>
mysql 常用
查看>>
MySQL 常用列类型
查看>>
mysql 常用命令
查看>>