【OpenCV • c++】图像噪音 | 椒盐噪音 | 高斯噪音

news/2025/1/11 20:44:01/

文章目录

    • 一、什么是图像噪音
    • 二、椒盐噪声
    • 三、高斯噪声

一、什么是图像噪音

  图像噪声是图像在获取或是传输过程中受到随机信号干扰,妨碍人们对图像理解及分析处理的信号。很多时候将图像噪声看做多维随机过程,因而描述噪声的方法完全可以借用随机过程的描述, 也就是用它的概率分布函数和概率密度分布函数。图像噪声的产生来自图像获取中的环境条件和传感元器件自身的质量,图像在传输过程中产生图像噪声的主要因素是所用的传输信道受到了噪声的污染。

二、椒盐噪声

  椒盐噪声是数字图像中的常见噪声,一般是由图像传感器、传输信道及解码处理等产生的黑白相见的亮暗点噪声,椒盐噪声常由图像切割产生。椒盐噪声是指两种噪声:盐噪声(salt noise)及椒噪声(pepper noise)。盐噪声一般是白色噪声,椒噪声一般是黑色噪声,前者高灰度噪声,后者属于低灰度噪声,一般两种噪声同时出现,呈现在图像上就是黑白杂点。图像去除脉冲干扰及椒盐噪声最常用的算法是中值滤波,图像模拟添加椒盐噪声是通过随机获取像素值点并设置为高亮点来实现的。
  下面时

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdlib>
using namespace cv;// 向图像添加椒盐噪声的函数
Mat addSaltNoise(Mat srcImage, int n)
{Mat resultImage = srcImage.clone();// 循环添加椒盐噪声'n'次for (int k = 0; k < n; k++){// 随机选择一个像素位置int i = rand() % resultImage.cols;int j = rand() % resultImage.rows;// 检查图像的通道数// 如果是灰度图像(1个通道),将像素值设置为255if (resultImage.channels() == 1)resultImage.at<uchar>(j, i) = 255;else // 如果是彩色图像(3个通道),将所有通道的值都设置为255{resultImage.at<Vec3b>(j, i)[0] = 255;resultImage.at<Vec3b>(j, i)[1] = 255;resultImage.at<Vec3b>(j, i)[2] = 255;}}return resultImage;
}int main()
{// 从文件加载源图像Mat srcImage = imread("C://Users//86173//Desktop//cc.png");// 检查图像数据是否成功加载if (!srcImage.data)return -1;// 调用addSaltNoise函数,传入源图像和要添加的噪声像素数量Mat resultImage = addSaltNoise(srcImage, 5000);// 显示原始图像和带有噪声的图像imshow("srcImage", srcImage);imshow("resultImage", resultImage);// 等待按键输入,然后退出程序waitKey(0);return 0;
}

在这里插入图片描述

三、高斯噪声

  高斯噪声是指概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度服从高斯分布,而它的功率谱密度又是分布均匀的,则称它为高斯白噪声。高斯白噪声的二阶矩不想关,一阶矩为常数,是指先后信号在时间上的相关性。高斯白噪声包括热噪声和散粒噪声。高斯噪声完全由其时变平均值和两瞬时的协方差函数来确定,若噪声为平稳的,则平均值与时间无关,而协方差函数则变成仅和所考虑的两瞬时之方差有关的相关函数,它在意义上等效于功率谱密度。高斯噪声可以由大量独立的脉冲产生,从而在任何有限时间间隔内,这些脉冲中的每一个脉冲值与所有脉冲值的总和相比都可以忽略不计。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <cstdlib>
#include <limits>
#include <cmath>using namespace cv;
using namespace std;// 生成高斯分布的随机数
double generateGaussianNoise(double mu, double sigma)
{// 定义一个特别小的值const double epsilon = numeric_limits<double>::min();static double z0, z1;static bool flag = false;flag = !flag;// flag为假,构造高斯随机变量if (!flag)return z1 * sigma + mu;double u1, u2;// 构造随机变量do{u1 = rand() * (1.0 / RAND_MAX);u2 = rand() * (1.0 / RAND_MAX);} while (u1 <= epsilon);// flag为真构造高斯随机变量Xz0 = sqrt(-2.0 * log(u1)) * cos(2 * CV_PI * u2);z1 = sqrt(-2.0 * log(u1)) * sin(2 * CV_PI * u2);return z1 * sigma + mu;
}// 为图像添加高斯噪声
Mat addGaussianNoise(Mat& srcImage)
{Mat resultImage = srcImage.clone();    // 深拷贝,克隆int channels = resultImage.channels();    // 获取图像的通道int nRows = resultImage.rows;    // 图像的行数int nCols = resultImage.cols * channels;   // 图像的总列数// 判断图像的连续性if (resultImage.isContinuous())    // 判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组{nCols *= nRows;nRows = 1;}for (int i = 0; i < nRows; i++){for (int j = 0; j < nCols; j++){// 添加高斯噪声int val = resultImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32;if (val < 0)val = 0;if (val > 255)val = 255;resultImage.ptr<uchar>(i)[j] = (uchar)val;}}return resultImage;
}int main()
{Mat srcImage = imread("C://Users//86173//Desktop//cc.png");if (!srcImage.data)return -1;imshow("srcImage", srcImage);Mat resultImage = addGaussianNoise(srcImage);imshow("resultImage", resultImage);waitKey(0);return 0;
}

在这里插入图片描述

  • 🚀 个人简介:CSDN「博客新星」TOP 10 , C/C++ 领域新星创作者
  • 💟 作    者:锡兰_CC ❣️
  • 📝 专    栏:【OpenCV • c++】计算机视觉
  • 🌈 若有帮助,还请关注➕点赞➕收藏,不行的话我再努努力💪💪💪

更多专栏订阅推荐:

  • 👍 【开卷数据结构】
  • 💛 【备战蓝桥,冲击省一】
  • 💕   从零开始的 c++ 之旅
  • 💖 【OpenCV • c++】计算机视觉


http://www.ppmy.cn/news/1107869.html

相关文章

vue实现鼠标拖拽div左右移动的功能

直接代码&#xff1a; <template><div class"demo"><div class"third-part" id"发展历程"><div class"title">发展历程</div><div class"content" id"nav" v-if"dataList…

如何像专业人士一样调试 Kubernetes 应用程序错误(二)

接上一篇《如何像专业人士一样调试 Kubernetes 应用程序错误&#xff08;一&#xff09;》。继续我们的调试之旅&#xff0c;我们继续创建部署定义&#xff1a; kubectl create deploy nginx --imagenginx --dry-runclient -o yaml > deploy-nginx-course.yaml -- sleep 23…

计算机网络篇之IP地址

计算机网络篇之IP地址 文章目录 计算机网络篇之IP地址概括IPv4地址IPv6地址分配总结 概括 IP地址是计算机网络中用于标识和定位设备的一组数字&#xff0c;IP地址分为IPv4和IPv6两种格式 IPv4地址 IPv4地址是32位的二进制数&#xff0c;通常表示为四个用点分隔的十进制数&am…

浅析-ES6

4、ES6 语法指南 后端项目搭建完毕&#xff0c;接下来就是前端页面了。不过在这之前需要一些准备工作。我们需要学习ES6的语法标准。 什么是ES6&#xff1f;就是ECMAScript第6版标准。 4.1.什么是ECMAScript&#xff1f; 来看下前端的发展历程&#xff1a; web1.0时代&…

消息队列MQ

一、消息队列 网络端的Http请求默认采用的是同步请求方式&#xff0c;客户端与服务器端是基于请求和响应模式进行通信的。也就意味着&#xff0c;客户端发起请求。必须要等待服务器端完成处理结果给客户端才能继续进行下一步操作&#xff0c;如果服务器发送网络延迟、宕机、卡顿…

从业 20 年的行业老炮儿,如何看待 AI 的风险与能力边界?

点击文末“阅读原文”即可参与节目互动 后期 / 卷圈 监制 / 姝琦 产品统筹 / bobo 联合制作 / RTE开发者社区 随着近期 AIGC 技术和应用的发展落地&#xff0c;有人期待有人担忧&#xff0c;「AI for Social Good」再次成为一个避不开的热门话题。构建 AI 的未来&#xff0c;…

Flash存储芯片:NOR Flash、NAND Flash、UFS和eMMC的比较与解析

前言 在数字化时代的今天&#xff0c;数据的存储和管理变得越来越重要。各种各样的存储技术应运而生&#xff0c;以满足不同的使用场景和需求。其中&#xff0c;Flash存储芯片以其非易失性、可擦写性和可编程性等优势&#xff0c;占据了重要地位。本博客将详细介绍Flash存储芯片…

WebSocket vs SSE: 实时数据推送到前端的选择与实现(详细)

Websocket和Server-Sent Events 对比推送数据给前端及各自的实现 二者对比WebSocket&#xff1a;Server-Sent Events (SSE)&#xff1a;选择 WebSocket 还是 SSE&#xff1a; Websocket 实现使用原生 WebSocket API&#xff1a;使用 Netty 创建 WebSocket&#xff1a;总结和选择…