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

news2024/12/22 20:30:30

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.coloradmin.cn/o/1564504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DFS:深搜+回溯+剪枝解决排列、子集问题

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、全排列I . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://全局变量vector<vector<int>> ret;vector<int> path;bool check[6];vector<vector<int>> perm…

【NLP】LLM 和 RAG

在这里&#xff0c;我描述了我在过去几年中关于 RAG 系统如何发展的主要经验。分享 Naive RAG、Advanced RAG 和 Modular RAG 框架之间的区别。总结了高云帆等人发表的一篇出色的RAG 技术调查论文的关键见解。 什么是 RAG 框架&#xff1f; OpenAI的GPT系列、Meta的LLama系列…

InterliJ IDEA基本设置

安装好idea后&#xff0c;将软件打开&#xff0c;可以进行基础设置 1.打开软件&#xff0c;先安装插件-汉化包&#xff08;不推荐&#xff0c;最好使用英文版&#xff09;&#xff0c;本次我们使用汉化版本完成基本设置&#xff0c;后期希望大家适应英文版的开发环境。&#x…

Databend 开源周报第 138 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 支持多表插入 …

一次MySQL事务的旅程:Buffer Pool, Binlog, Redo Log揭秘

MySQL中的各种Buffer和Log以及表空间 MySQL中一次事务涉及了各种Buffer,Log和表空间&#xff0c;主要涉及&#xff1a;Buffer Pool, Binlog, Undo Log, Redo Log以及表空间。 我们来探讨下。 Buffer Pool Buffer Pool主要存放在内存中&#xff0c;它是一个缓存区域&#xf…

论文阅读RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection

文章目录 RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection问题笛卡尔坐标结构图Meta-Kernel Convolution RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection 论文&#xff1a;https://arxiv.org/pdf/2103.10039.pdf 代码&…

Python 与机器学习,在服务器使用过程中,常用的 Linux 命令包括哪些?

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 本博客旨在分享在实际开发过程中&#xff0c;开发者需要了解并熟练运用的 Linux 操作系统常用命令。Linux 作为一种操作系统&#xff0c;与 Windows 或 MacOS 并驾齐驱&#xff0c;尤其在服务器和开发环…

【Node.js从基础到高级运用】二十一、使用child_process模块创建子进程

引言 在Node.js中&#xff0c;child_process模块是一个提供了创建和管理子进程的能力的核心模块。通过使用child_process模块&#xff0c;Node.js可以执行系统命令、运行其他脚本或应用程序&#xff0c;实现与Node.js进程的并行处理。 child_process模块提供了几种创建子进程的…

环信IM集成教程——Web端UIKit快速集成与消息发送

写在前面&#xff1a; 千呼万唤始出来&#xff0c;环信Web端终于出UIKit了&#xff01;&#x1f389;&#x1f389;&#x1f389; 文档地址&#xff1a;https://doc.easemob.com/uikit/chatuikit/web/chatuikit_overview.html 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开…

Docker:探索容器化技术,重塑云计算时代应用交付与管理

一&#xff0c;引言 在云计算时代&#xff0c;随着开发者逐步将应用迁移至云端以减轻硬件管理负担&#xff0c;软件配置与环境一致性问题日益凸显。Docker的横空出世&#xff0c;恰好为软件开发者带来了全新的解决方案&#xff0c;它革新了软件的打包、分发和管理方式&#xff…

聚观早报 | 蔚来推出油车置换补贴;iPhone 16 Pro细节曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月02日消息 蔚来推出油车置换补贴 iPhone 16 Pro细节曝光 小米SU7创始版第二轮追加开售 OpenAI将在日本设立办事…

OSPF中配置静态路由实验简述

静态路由协议和OSPF&#xff08;开放最短路径优先&#xff09;协议是两种常见的路由协议&#xff0c;它们在路由选择和网络管理方面有一些区别。他们可以共存。 静态路由协议需要手动配置路由表&#xff0c;不会自动适应网络拓扑变化&#xff0c;适用于小型网络或者网络拓扑变化…

图神经网络:处理非欧几里得数据的新视角

目录 1. 引言 2.图数据与图神经网络基础 3.GNN模型详解 4.应用案例 4.1. 社交网络分析 4.2. 化学分子性质预测 5.总结 1. 引言 非欧几里得数据指的是那些不遵循传统欧几里得空间几何规则的数据。在欧几里得空间中&#xff0c;数据点之间的距离和形状可以通过标准的几何度…

书生·浦语大模型(学习笔记-1)

一、大模型的发展 模型与通用人工智能&#xff08;AGI&#xff09;&#xff0c;大模型通常被视为发展通用人工智能的重要途径。AI研究从专用模型向通用模型转变&#xff0c;在过去的一二十年中&#xff0c;研究重点在于针对特定任务的专用模型。专用模型的已经再多个领域取得显…

试过了,ChatGPT确实不用注册就可以使用了!

看到官网说不用登录也可以直接使用ChatGPT 我们来试一下 直接打开官网 默认是直接进入了chatgpt3.5的聊天界面 之前是默认进的登录页面 聊一下试试 直接回复了&#xff0c;目前属于未登录状态&#xff0c;挺好&#xff01; 来试下ChatGPT4 跳转到了登录页面 目前来看gpt4还…

时序预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络时间序列预测

时序预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现CPO-LSTM【24年新算法】冠豪猪优化长短期记忆神经网络时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-LSTM【24年新算法】…

【Java+Springboot】----- 通过Idea快速创建SpringBoot项目操作方法

一、第一步&#xff1a; 点击选择【File】->【New】-> 【Project】 最后弹出[new Project]界面。 二、第二步&#xff1a; 1. 选择【Spring Initializr】 2. 然后选择【Project SDK】的版本 3. 然后 Choose Initializr Service URL 选择默认&#xff08;Default&#x…

OpenCV项目实战-深度学习去阴影-图像去阴影

往期热门博客项目回顾&#xff1a; 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 //正文开始&#xff01; 图…

Python+requests+Pytest+logging+allure+pymysql框架详解

一、框架目录结构 1)tools目录用来放公共方法存储,如发送接口以及读取测试数据的方法,响应断言 数据库断言 前置sql等方法;2)datas目录用例存储接口用例的测试数据,我是用excel来存储的数据,文件数据 图片数据等;3)testcases目录用来存放测试用例,一个python文件对应…

linux删除 buff/cache缓存

1.查看当前内存占用 free -h如图&#xff0c;缓存占用了将近9G&#xff0c;接下来进行清理 释放页缓存 echo 1 > /proc/sys/vm/drop_caches释放dentries和inodes echo 2 > /proc/sys/vm/drop_caches释放所有缓存 echo 3 > /proc/sys/vm/drop_caches再次查看&#…