【OpenCV】噪声的添加和过滤

2023-10-29

1. 简介
下面简单介绍两种图像噪声,即椒盐噪声和高斯噪声。

(1) 椒盐噪声 
椒盐噪声也称脉冲噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。 
图像模拟添加椒盐噪声是通过:随机获取像素点,并设置为高亮度点和低亮度点来实现的。

(2) 高斯噪声 
高斯噪声是指概率密度函数服从高斯分布的一类噪声。 
特别的,如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度服从均匀分布,则称这个噪声为高斯白噪声。 
高斯白噪声 功率谱密度频谱图 和 噪声幅值分布图的图片如下:

2. 代码

(1) 为图像添加椒盐噪声

//给原图像增加椒盐噪声
//图象模拟添加椒盐噪声是通过随机获取像素点,并设置为高亮度点和低亮度点来实现的
//srcImage为源图像,n为椒/盐像素点个数,返回含噪图像
Mat addSaltNoise(const Mat srcImage, int n)
{
    Mat dstImage = srcImage.clone();

    for (int k = 0; k < n; k++)
    {
        //随机取值行列,得到像素点(i,j)
        int i = rand() % dstImage.rows;
        int j = rand() % dstImage.cols;

        //图像通道判定
        if (dstImage.channels() == 1)//修改像素点(i,j)的像素值
        {
            dstImage.at<uchar>(i, j) = 255;     //盐噪声
        }
        else
        {
            dstImage.at<Vec3b>(i, j)[0] = 255;
            dstImage.at<Vec3b>(i, j)[1] = 255;
            dstImage.at<Vec3b>(i, j)[2] = 255;
        }
    }

    for (int k = 0; k < n; k++)
    {
        //随机取值行列
        int i = rand() % dstImage.rows;
        int j = rand() % dstImage.cols;
        //图像通道判定
        if (dstImage.channels() == 1)
        {
            dstImage.at<uchar>(i, j) = 0;       //椒噪声
        }
        else
        {
            dstImage.at<Vec3b>(i, j)[0] = 0;
            dstImage.at<Vec3b>(i, j)[1] = 0;
            dstImage.at<Vec3b>(i, j)[2] = 0;
        }
    }
    return dstImage;
}

(2) 为图像增加高斯噪声 方法1

此算法原理我没仔细看,但是能够成功为图像增加高斯噪声。相比来说,方法2简单得多。 
参考网址:【OpenCV】给图像添加噪声

原理:

根据Box-Muller变换原理,假设随机变量U1、U2相互独立,且均服从(0,1)之间的均匀分布,则经过下面两个式子产生的随机变量Z0,Z1服从标准高斯分布。 
 这里写图片描述
上式中Z0,Z1满足正态分布,其中均值为0,方差为1,变量U1和U2可以修改为下式: 

代码:

//生成高斯噪声
double generateGaussianNoise(double mu, double sigma)
{
    //定义小值
    const double epsilon = numeric_limits<double>::min();
    static double z0, z1;
    static bool flag = false;
    flag = !flag;
    //flag为假构造高斯随机变量X
    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为真构造高斯随机变量
    z0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI*u2);
    z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI*u2);
    return z0*sigma + mu;
}


//为图像添加高斯噪声
Mat addGaussianNoise(Mat &srcImag)
{
    Mat dstImage = srcImag.clone();
    int channels = dstImage.channels();
    int rowsNumber = dstImage.rows;
    int colsNumber = dstImage.cols*channels;
    //判断图像的连续性
    if (dstImage.isContinuous())
    {
        colsNumber *= rowsNumber;
        rowsNumber = 1;
    }
    for (int i = 0; i < rowsNumber; i++)
    {
        for (int j = 0; j < colsNumber; j++)
        {
            //添加高斯噪声
            int val = dstImage.ptr<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32;
            if (val < 0)
                val = 0;
            if (val>255)
                val = 255;
            dstImage.ptr<uchar>(i)[j] = (uchar)val;
        }
    }
    return dstImage;
}

(3) 为图像增加高斯噪声 方法2(简单)

原理:用OpenCV的RNG类,为图像添加高斯噪声。

在OpenCV中,可用RNG (Random number generator) 类来产生均匀分布和正态分布(高斯分布)的随机数。

可以用RNG类的成员函数fill,来为图像添加高斯噪声。fill的原型(C++)如下:

void RNG::fill(InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false )
1
参数意义如下:

mat:二维或多维矩阵,目前版本中,维数不能超过4。
distType:随机数的分布类型。有两种,即RNG::UNIFORM 或 RNG::NORMAL。前者表示均匀分布,后者表示正态分布(即高斯分布)。
a:分布规律参数之一。在均匀分布中表示下限(包含);在正态分布(即高斯分布)中,表示均值。
b:分布规律参数之一。在均匀分布中表示上限(包含);在正态分布(即高斯分布)中,表示标准差。
saturateRange:这个参数只对均匀分布时有用。
用fill构造一个均值为a,标准差为b的噪声矩阵(与原图像大小,类型相同),将噪声矩阵与原图像相加,即可得到含噪图像。

代码:
 

Mat anotherAddGaussianNoise(Mat &srcImg)
{
    Mat tempSrcImg = srcImg.clone();
    Mat img_output(tempSrcImg.size(), tempSrcImg.type());

    //构造高斯噪声矩阵
    Mat noise(tempSrcImg.size(), tempSrcImg.type());//创建一个噪声矩阵
    RNG rng(time(NULL));
    rng.fill(noise, RNG::NORMAL, 10, 36);//高斯分布;均值为10,标准差为36

    //将高斯噪声矩阵与原图像叠加得到含噪图像
    cv::add(tempSrcImg, noise, img_output);

    return img_output;
}

(4) 测试代码:

#include <cmath>
#include <limits>
#include <cstdlib>
#include <iostream>
#include <cvInclude.h>
#include <time.h> 

using namespace std;

Mat addSaltNoise(const Mat srcImage, int n);
Mat addGaussianNoise(Mat &srcImag);
Mat anotherAddGaussianNoise(Mat &srcImg);


int main()
{
    Mat srcImage = imread("F:/test_photo/zhongshuo.jpg");
    if (!srcImage.data)
    {
        cout << "读入图像有误!" << endl;
        system("pause");
        return -1;
    }
    imshow("原图像", srcImage);

    Mat dstSaltImage = addSaltNoise(srcImage, 3000);
    imshow("添加椒盐噪声的图像", dstSaltImage);
    imwrite("F:/test_photo/zhongshuoSalt.jpg", dstSaltImage);//存储图像

    Mat dstGaussImage = addGaussianNoise(srcImage);
    imshow("添加高斯噪声后的图像1", dstGaussImage);
    imwrite("F:/test_photo/zhongshuoGauss1.jpg", dstGaussImage);//存储图像

    Mat anotherDstGaussImage = anotherAddGaussianNoise(srcImage);
    imshow("添加高斯噪声后的图像2", anotherDstGaussImage);
    imwrite("F:/test_photo/zhongshuoGauss2.jpg", anotherDstGaussImage);//存储图像

    waitKey();
    return 0;
}

给图像添加各种噪声

OpenCv基础(一):噪声的添加和过滤

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【OpenCV】噪声的添加和过滤 的相关文章

随机推荐

  • Java实现异步的几种方式

    Java实现异步的几种方式 异步编程在对响应时间近乎严苛的今天 受到了越来越多的关注 尤其是在IO密集型业务中 对比传统的同步模式 异步编程可以提高服务器的响应时间和处理业务的能力 从而达到快速给用户响应的效果 代码前置 方法中会直接使用到
  • spring boot引入logback.xml

    logback xml
  • 使用@Value("${xxxx}")注解从配置文件读取值

    使用 Value xxxx 注解从配置文件读取值 记录一下自己学习配置文件读取的方法 假设配置文件为 config properties 1 从配置文件中读取值的用法 Value user username private String u
  • SpringCloud快速入门

    文章目录 1 初识 SpringCloud 1 1 微服务 1 2 简介 2 Eureka 注册中心 2 1 简易模拟一个微服务 2 1 1 搭建EurekaServer 2 1 2 注册到Eureka 2 1 3 从Eureka获取服务
  • golang 将字符串变量中的单引号、双引号和反单引号进行转义

    package main import strconv fmt func main var a string a qwe wer f lopg uiii 随便写的例子 因为字符串变量中的单双引号是我们不能提前知道的 b strconv Qu
  • 企业如何通过CRM系统做好客户管理?

    每一位客户对于企业都是非常宝贵的资源 也是企业赖以生存和发展的基础 做好客户管理和关系维护是企业必备的一种能力 如今 随着信息化的发展 很多企业为了更好的管理客户引进了CRM系统 CRM系统可以帮助企业建立 以客户为中心 的管理方式 将市场
  • 奥特曼系列赛文飞踢是哪个服务器,盘点奥特兄弟最强飞踢技,第一名实至名归你能猜到吗?...

    奥特曼系列较之拳头威力 飞踢这种技能的对比更为奥迷津津乐道 其中最具代表性的无疑是 雷欧飞踢 毕竟有数次杀敌纪录 而提起飞踢的威力对比 雷欧飞踢则不见得一定能傲视群雄 平成系暂且不论 在奥特兄弟中 也不乏能与雷欧飞踢分庭抗礼的飞踢技 力 解
  • 创建数据库(脚本实现)

    创建历史数据库 if object id dbo spr create his db is not null drop procedure dbo spr create his db go create proc dbo spr creat
  • matlab 正弦波 fft,【求助】正弦信号序列fft频谱分析!!!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 就是正弦包含频率是20hz 20 5hz 40hz 采样频率fs是100hz 分析栅栏效应 先是128个点fft 补零到512个点进行fft 再512个点fft 程序是这样的 N1 128 N2
  • innoDB数据收集方式—永久性&非永久性(四十三)

    上篇文章说了连接查询的成本 主要由驱动表的扇出值和被驱动表的查询方法决定 而成本这些都是可以在 cost 表查看的 因为分为server和engine表 server不管理数据成本 里面包含连接管理 查询缓存 sql解码 sql优化 eng
  • 动态类型语言和静态类型语言的区别

    一 概念 动态类型语言 动态类型语言是指在运行期间才去做数据类型检查的语言 也就是说 在用动态类型的语言编程时 永远也不用给任何变量指定数据类型 变量使用之前不需要类型声明 该语言会在你第一次赋值给变量时 在内部将数据类型记录下来 Pyth
  • MySQL · myrocks · 相关tools介绍

    概述 MyRocks提供了丰富的tools 如sst dump mysql ldb等 这些工具对我们的运维和分析问题非常有用 sst dump 可以导出sst中的数据和属性信息 sst dump help sst dump file
  • c# cst_CST407教学大纲-通过.NET学习C#

    c cst OREGON INSTITUTE OF TECHNOLOGY 俄勒冈理工学院 Software Engineering Technology 软件工程技术 CST 407 Seminar C and the NET Framew
  • unity3D实现多点触碰

    实现多点触碰是利用input这个类里面的方法实现的 从edit project settings input就可以看到input能够得到的轴 想要读取轴向可以使用Input GetAxis方法获取下列默认轴 Horizontal 和 Ver
  • 神秘又熟悉的main函数

    目录 1 概述 2 程序编译 3 揭开最后的面纱 1 概述 学习C语言的同学都知道main函数 并且这是我们接触的第一个函数 但是很少有人去深究C语言为什么都是从main函数执行的 今天我们就来深入了解下 2 程序编译 C语言生成可执行文件
  • HTML5语义元素

    目录 什么是语义元素 浏览器支持 HTML5 中新的语义元素 HTML5 语义元素 HTML5元素 实例 HTML5元素 实例 嵌套语义元素 HTML5元素 实例 HTML5元素 实例 HTML5元素 实例 HTML5元素 实例 HTML5
  • 凸优化第三章凸函数 3.1基本性质和例子

    3 1基本性质和例子 定义 扩展值延伸 一阶条件 二阶条件 例子 下水平集 上境图 Jensen不等式及其扩展 不等式 定义 函数f是凸函数 当f的定义域S是凸集 且 严格凸函数 从几何上来看 如下图 函数f上的任意两点之间的弦都在函数图像
  • 解决本地浏览器运行项目时的跨域问题Access to XMLHttpRequest at ‘file:///C:/Users/Len/Desktop/%E5%8F%AF%E4%BF%AE%E6%94%

    解决本地浏览器运行项目时的跨域问题 Access to XMLHttpRequest at file C Users Len Desktop E5 8F AF E4 BF AE E6 94 B9 E9 85 8D E7 BD AE dist
  • leetcode 路径总和 -- 递归

    0 题目描述 leetcode原题链接 112 路径总和 1 递归解法 假定从根节点到当前节点的值之和为 val 我们可以将这个大问题转化为一个小问题 是否存在从当前节点的子节点到叶子的路径 满足其路径和为 sum val 不难发现这满足递
  • 【OpenCV】噪声的添加和过滤

    1 简介 下面简单介绍两种图像噪声 即椒盐噪声和高斯噪声 1 椒盐噪声 椒盐噪声也称脉冲噪声 它是一种随机出现的白点或者黑点 可能是亮的区域有黑色像素或是在暗的区域有白色像素 或是两者皆有 图像模拟添加椒盐噪声是通过 随机获取像素点 并设置