OpenCV 笔记(28):图像降噪算法——中值滤波、高斯滤波

1.  图像噪声

图像降噪(Image Denoising)是指从图像中去除噪声的过程,目的是提高图像质量,增强图像的视觉效果。

图像噪声是指图像中不希望出现的随机亮度或颜色变化,通常会降低图像的清晰度和可辨识度,以及会降低图像的质量并使图像分析和理解更加困难。

图像噪声主要有以下几个原因来产生的:

  • 光线不足:光线不足会导致光子噪声增加,从而降低图像的信噪比。

  • 电子元器件的热噪声:电子元器件在工作时会产生热噪声,这种噪声会影响图像的质量。

  • 电路噪声:电路中的电磁干扰也会导致图像噪声的产生。

  • 图像传输过程中的错误:图像在传输过程中可能会受到各种干扰,从而导致图像噪声的产生。

根据噪声的统计特性来分类,可以将图像噪声分为以下几类:

  • 椒盐噪声:图像中随机出现黑白像素的噪声。

  • 高斯噪声:最常见的噪声类型,其概率密度函数服从高斯分布。

  • 泊松噪声:光子噪声的一种类型,其概率密度函数服从泊松分布。

  • 斑点噪声:由图像传感器坏点或污点引起的噪声。

下面的例子,分别展示了在图像中添加椒盐噪声、高斯噪声、泊松噪声和斑点噪声。

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <random>using namespace std;
using namespace cv;void addSaltNoise(Mat &src, int num, Mat &dst)
{dst = src.clone();// 随机数产生器std::random_device rd; //种子std::mt19937 gen(rd()); // 随机数引擎auto rows = src.rows; // 行数auto cols = src.cols * src.channels();for (int i = 0; i < num; i++){auto row = static_cast<int>(gen() % rows);auto col = static_cast<int>(gen() % cols);auto p = dst.ptr<uchar>(row);p[col++] = 255;p[col++] = 255;p[col] = 255;}
}void addGaussianNoise(Mat &src, int mu, int sigma, Mat &dst)
{dst = src.clone();// 产生高斯分布的随机数发生器std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<> d(mu, sigma);auto rows = src.rows; // 行数auto cols = src.cols * src.channels(); // 列数for (int i = 0; i < rows; i++){auto p = dst.ptr<uchar>(i); // 取得行首指针for (int j = 0; j < cols; j++){auto tmp = p[j] + d(gen);tmp = tmp > 255 ? 255 : tmp;tmp = tmp < 0 ? 0 : tmp;p[j] = tmp;}}
}typedef cv::Point3_<uint8_t> Pixel;void addPoissonNoise(const Mat& src, double lambda, Mat& dst) {dst = src.clone();// 产生泊松分布的随机数生成器std::random_device rd;std::mt19937 gen(rd());std::poisson_distribution<int> distribution(lambda);dst.forEach<Pixel>([&](Pixel &p, const int * position) -> void {int row = position[0];int col = position[1];int count = distribution(gen);dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(count, count, count);});
}void addSpeckleNoise(Mat& image, double scale, Mat &dst) {dst = image.clone();RNG rng;dst.forEach<Pixel>([&](Pixel &p, const int * position) -> void {int row = position[0];int col = position[1];double random_value = rng.uniform(0.0, 1.0);double noise_intensity = random_value * scale;dst.at<Vec3b>(row, col) = dst.at<Vec3b>(row, col) + Vec3b(noise_intensity * 255, noise_intensity * 255, noise_intensity * 255);});
}int main() {Mat src = imread(".../girl.jpg");imshow("src", src);Mat dst1;addSaltNoise(src,100000,dst1);imshow("addSaltNoise", dst1);Mat dst2;addGaussianNoise(src, 0, 50,dst2);imshow("addGaussianNoise", dst2);Mat dst3;addPoissonNoise(src, 60, dst3);imshow("addPoissonNoise", dst3);Mat dst4;addSpeckleNoise(src,0.5,dst4);imshow("addSpeckleNoise", dst4);waitKey(0);return 0;
}
c1d7363fa002050daef149db43c90f45.jpeg
原图和椒盐噪声.png
4c535b6c4bd01e75789240f8e086dcb7.jpeg
原图和高斯噪声.png
b63618e72864e694b0564fc071accec8.jpeg
原图和泊松噪声.png
27c13b378203a94fa5b0832f7212dddd.jpeg
原图和斑点噪声.png

2.  图像降噪方法

传统的图像处理是基于滤波器的方式进行降噪,比如使用空域滤波、频域滤波、非局部均值滤波等等,还有使用形态学降噪,当然也可以深度学习的方式进行降噪。

本文介绍两种空域滤波的方式进行降噪。

2.1 中值滤波

中值滤波是一种非线性滤波器,它通过对图像中的像素值进行排序并取中间值来进行滤波处理。

211443c7edff35e836e7214fe1f9cfe4.jpeg
中值滤波.png

中值滤波的特性:

  • 对于图像中的每个像素,选取其周围一定区域内的所有像素值,并对其进行排序。

  • 将排序后的像素值的中位数赋予该像素。

中值滤波的优点:

  • 能够有效去除椒盐噪声和脉冲噪声,对图像中的孤立噪声点具有较强的抑制能力。

  • 能够较好地保留图像的边缘和细节信息,不会造成图像模糊。

中值滤波的缺点:

  • 对高斯噪声的去除效果不佳。

  • 计算量相对较大,特别是对于大尺寸图像而言。

2.2 高斯滤波

高斯滤波是一种线性平滑滤波器,它利用高斯函数对图像进行加权平均,可以有效地去除高斯噪声,同时平滑图像。

高斯滤波的优点:

  • 高斯滤波具有良好的平滑效果,能够有效地抑制图像中的噪声。

  • 高斯滤波是一种线性滤波器,具有可分离性,可以提高计算效率。

  • 高斯滤波在频域上具有低通滤波器的特性,能够去除图像中的高频噪声。

高斯滤波的缺点:

  • 高斯滤波会造成图像细节丢失,降低图像锐度。

  • 高斯滤波对椒盐噪声等非平滑噪声的去除效果不佳。

高斯滤波以使用两种方法实现:一种是离散化窗口滑窗卷积,另一种方法是通过傅里叶变化。最常见的就是滑窗卷积实现。

先来回顾一下一维高斯函数:

b768a42a813e75455854d2219f856c6f.jpeg
一维高斯函数.png

其中,是 x 的均值,是 x 的方差。x 是卷积核内任意一点的坐标,是卷积核中心的坐标。当 = 0 时,

由于图像是二维的,二维的高斯函数则是对 x、y 两个方向的一维高斯函数的乘积:

当时,就是我们比较熟悉的二维高斯函数公式:

54eb6c98a0e48d30207115e71bdd0fcd.jpeg
二维高斯函数.png

常用的高斯模板有如下几种形式,它们是基于高斯函数计算出来的。

2584062de5b44025cb3dc9e2a29866db.jpeg
高斯模版.png

高斯滤波具有以下性质:

  • 线性: 高斯滤波器是线性的,这意味着它可以与其他滤波器组合使用。例如,可以先使用高斯滤波器去除噪声,然后再使用边缘检测滤波器检测边缘。

  • 可分离性: 高斯滤波器可以分离为两个一维滤波器,即水平方向和垂直方向的滤波器。这使得高斯滤波器的计算效率更高。

  • 傅里叶变换: 高斯滤波器的傅里叶变换是一个低通滤波器,这意味着它可以抑制图像中的高频成分,而保留低频成分。

  • 旋转不变性: 高斯滤波器在各个方向上具有相同的平滑效果,这意味着它不会改变图像的旋转方向。

  • 尺度不变性: 高斯滤波器的尺度可以通过调整高斯函数的标准差来控制。标准差越大,滤波器的平滑效果越强。

下面的例子,分别使用中值滤波和高斯滤波消除椒盐噪声和高斯噪声。

int main() {Mat src = imread(".../girl.jpg");imshow("src", src);Mat result;Mat dst1;addSaltNoise(src,100000,dst1);imshow("addSaltNoise", dst1);int a = 7;medianBlur(dst1, result,a);imshow("removeSaltNoise", result);Mat dst2;addGaussianNoise(src, 0, 50,dst2);imshow("addGaussianNoise", dst2);GaussianBlur(dst2, result, Size(15, 15), 0, 0);imshow("removeGaussianNoise", result);waitKey(0);return 0;
}


d0987a6605cdcd729105185cd4f77ba7.jpeg

椒盐噪声和中值滤波后的效果.jpeg
710265b61ffad4cca91819f4348d78a7.jpeg
高斯噪声和高斯滤波后的效果.png

3.  总结

图像降噪可以提高图像质量、提高图像分析和处理的准确性、提高图像压缩效率以及扩展图像应用范围。

本文介绍了两种简单的降噪算法。中值滤波适用于去除椒盐噪声和脉冲噪声,常用于图像修复和增强。高斯滤波适用于去除高斯噪声、平滑图像,常用于图像预处理和模糊处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/587830.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中发送HTTP请求的方式

一&#xff0c;简介 使用C编程发送HTTP请求通常需要使用第三方的HTTP库或框架。在C中&#xff0c;有几个受欢迎的HTTP库可供选择&#xff0c;例如Curl、Boost.Beast和cpp-httplib。另外&#xff0c;也可以自己实现socket来发送http请求 二、使用Curl库发送HTTP请求 1. 确认当…

docker搭建CI/CD环境配置过程中的常见问题

一、Jenkins 1、pull镜像问题 docker pull jenkins/jenkins:lts Using default tag: latest Trying to pull repository docker.io/library/centos ... Get https://registry-1.docker.io/v2/library/centos/manifests/latest: Get https://auth.docker.io/token?scoperepo…

【C++】哈希之位图

目录 一、位图概念二、海量数据面试题 一、位图概念 假如有40亿个无重复且没有排序的无符号整数&#xff0c;给一个无符号整数&#xff0c;如何判断这个整数是否在这40亿个数中&#xff1f; 我们用以前的思路有这些&#xff1a; 把这40亿个数遍历一遍&#xff0c;直到找到为…

4月2号总结

java学习 一.final关键字 final英语翻译过来的意思是“最后&#xff0c;最终”的意思。 在java中&#xff0c;final有三个作用&#xff0c;修饰变量、修饰类、修饰成员方法。 1.修饰变量 final修饰的变量只能被赋值一次&#xff0c;不能被改变。 要是强行去改变final修饰…

服务器端口被扫会发生哪些故障?

在数字化时代&#xff0c;服务器作为支撑各种业务运行的核心基础设施&#xff0c;其安全性至关重要。然而&#xff0c;当服务器的端口被恶意扫描时&#xff0c;可能会引发一系列故障&#xff0c;给企业和个人带来不可估量的损失。那么&#xff0c;服务器端口被扫会发生哪些故障…

物联网实战--入门篇之(十)安卓QT--后端开发

目录 一、项目配置 二、MQTT连接 三、数据解析 四、数据更新 五、数据发送 六、指令下发 一、项目配置 按常规新建一个Quick空项目后&#xff0c;我们需要对项目内容稍微改造、规划下。 首先根据我们的需要在.pro文件内添加必要的模块&#xff0c;其中quick就是qml了&…

vue3项目运行正常但vscode红色波浪线报错

以下解决办法如不生效&#xff0c;可尝试 重启 vscode 一、Vetur插件检测问题 vetur 是一个 vscode 插件&#xff0c;用于为 .vue 单文件组件提供代码高亮以及语法支持。但 vue 以及 vetur 对于 ts 的支持&#xff0c;并不友好。 1、原因 如下图&#xff1a;鼠标放到红色波浪…

负载均衡集群

一、集群的基本原理 集群&#xff1a;数据内容是一致的&#xff0c;集群可以被替代 分布式&#xff1a;各司其职&#xff0c;每台服务器存储自己独有的数据&#xff0c;对外作为单点被访问是访问整体的数据&#xff1b; 分布式是不能被替代的&#xff1b;分布式分为MFS、GFS、…

Spring Boot | Spring Boot “整合JPA“

目录 &#xff1a; 一、Spring Data JPA”介绍“二、Spring Data JPA”要进行的操作“ :① 编写ORM “实体类” ( 编写“数据库表”对应的“实体类” 配置“映射关系”的“注解”)② 编写 Repository 接口 ( 继承“JpaRepository接口” 其中的“操作数据库”的方法 通过“注…

debian的使用笔记

1. XP风格任务栏 安装 debian-live-12.5.0-amd64-xfce.iso 后&#xff0c;把下面的任务栏删除&#xff0c;把上面的任务栏移到下面&#xff0c;然后设置如下选项 2. 命令自动补全 sudo apt install bash-completion 3. 找不到命令 sudo apt install command-not-found sudo…

拥塞控制算法系列之:Swift-谷歌2020年SIGCOM-包级别端到端TIMELY拥塞控制算法

核心要点&#xff1a; 谷歌 2020 SIGCOM基于delay的AIMD拥塞拆分EC和FC&#xff0c;时延敏感场景优势分别计算EC和FC的wnd&#xff08;最核心&#xff09;保障吞吐和低延迟。Swift 因利用延迟的简单性和有效性而闻名包级别的论文&#xff1a;https://dl.acm.org/doi/pdf/10.11…

【25考研】:四川大学计算机学院24届874考研考情分析

去年的考情分析也是我做的&#xff0c; 今年就在去年的基础上做了。保持形式不变&#xff0c;更改数据。 21考情&#xff1a; 万载月寒肠断客&#xff1a;四川大学计算机学院21届CS考研考情分析 22考情&#xff1a; 懒羊羊&#xff1a;四川大学计算机学院2022考研考情分析 2…