C++ OpenCV实现与添加椒盐噪声和高斯噪音

 更新时间:2023年09月13日 09:47:01   作者:锡兰_CC  
图像噪声是图像在获取或是传输过程中受到随机信号干扰,妨碍人们对图像理解及分析处理的信号,本文为大家整理了C++结合OpenCV为图像添加椒盐噪声和高斯噪音的代码,需要的可以收藏一下

一、什么是图像噪音

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

二、椒盐噪声

椒盐噪声是数字图像中的常见噪声,一般是由图像传感器、传输信道及解码处理等产生的黑白相见的亮暗点噪声,椒盐噪声常由图像切割产生。椒盐噪声是指两种噪声:盐噪声(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个通道),将像素值设置为255
		if (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为真构造高斯随机变量X
    z0 = 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;
}

效果图

以上就是C++ OpenCV实现与添加椒盐噪声和高斯噪音的详细内容,更多关于C++ OpenCV噪声的资料请关注脚本之家其它相关文章!

相关文章

  • 解析C/C++指针、函数、结构体、共用体

    解析C/C++指针、函数、结构体、共用体

    这篇文章主要介绍了C/C++指针、函数、结构体、共用体的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • 浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    下面小编就为大家带来一篇浅谈带缓冲I/O 和不带缓冲I/O的区别与联系。小编觉得挺不错的现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • C++实现LeetCode(43.字符串相乘)

    C++实现LeetCode(43.字符串相乘)

    这篇文章主要介绍了C++实现LeetCode(43.字符串相乘),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++中构造函数的参数缺省的详解

    C++中构造函数的参数缺省的详解

    这篇文章主要介绍了C++中构造函数的参数缺省的详解的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-10-10
  • 详解C语言学习记录之指针

    详解C语言学习记录之指针

    关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏。其实指针并不复杂,学习指针,要正确的理解指针,本片文章能给就来学习一下
    2021-11-11
  • 深入C++四种强制类型转换的总结

    深入C++四种强制类型转换的总结

    本篇文章是对C++中四种强制类型转换进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 浅析C++中的函数与指针

    浅析C++中的函数与指针

    这篇文章主要介绍了浅析C++中的函数与指针,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • c++11多线程编程之std::async的介绍与实例

    c++11多线程编程之std::async的介绍与实例

    这篇文章主要给大家介绍了关于c++11多线程编程之std::async的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • C++实现Window环境聊天室功能

    C++实现Window环境聊天室功能

    这篇文章主要为大家详细介绍了C++实现Window环境聊天室功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++实现单张图片读取和保存

    C++实现单张图片读取和保存

    这篇文章主要为大家详细介绍了C++语言读取和保存单张图片的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09

最新评论