OpenCV实现图像噪声、去噪基本方法

一、噪声分类

1、高斯噪声

指服从高斯分布(正态分布)的一类噪声,其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的,同时相机长时间工作使得温度过高也会引起高斯噪声,另外电路元器件白身噪声和互相影响也是造成高斯噪声的重要原因之一。

概率密度函数(PDF)如下:

初始图片:

注意加噪声时,不能直接将 noise+img,不然最终出来的是一片空白和零星几个噪点,原因在于cv2.imshow输入要求是 0-1 float 或者 0-255 int。

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   cv2.imshow('Gauss noise',img)
cv2.waitKey(0)

3)高斯滤波

高斯滤波是一种线性平滑滤波,一般用于消除高斯噪声。对于每一个像素点的值,是由其本身和邻域内的其他像素值经过加权平均后得到。

二维高斯函数:

具体过程:

代码:使用cv2.GaussianBlur()函数

注意高斯模糊半径不能为偶数

滤波结果:

2、泊松噪声

简言之就是符合泊松分布的噪声模型,又称散粒噪声。

使用**np.random.poisson()**函数

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生泊松噪声
noise = np.random.poisson(lam=20,size=img.shape).astype('uint8')# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255cv2.imshow('Poisson noise',img)
cv2.waitKey(0)

λ值越大,噪声程度越深。

3、椒盐噪声

椒盐噪声又称为脉冲噪声,是在图像上随机出现黑色白色的像素,顾名思义就是椒盐噪声 = 椒噪声(值为0,黑色) + 盐噪声(值为255,白色)

直接上代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 转化成向量
x = img.reshape(1,-1)  
# 设置信噪比
SNR = 0.85
# 得到要加噪的像素数目
noise_num = x.size * (1-SNR)
# 得到需要加噪的像素值的位置
list = random.sample(range(0,x.size),int(noise_num))for i in list:if random.random() >= 0.5:x[0][i] = 0else:x[0][i] = 255
img1 = x.reshape(img.shape)cv2.imshow('salt&pepper noise',img1)
cv2.waitKey(0)

SNR越小,噪声越大。

4、瑞利噪声

一般是由由信道不理想引起的,它与信号的关系是相乘,信号在它在,信号不在他也就不在。

瑞利密度对倾斜形状直方图的建模非常有用。

在生成瑞利噪声的时候,其实采用的是**np.random.rayleigh()** 方法生成,而这个方法就是根据第二个公式来的,所以只需要指定1个参数,得到的分布和第一个公式相比本质是相同的。

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生瑞利噪声
sigma = 70.0
noise = np.random.rayleigh(sigma, size=img.shape)
# 可以试试下面这个效果
# noise = np.random.rayleigh(img, size=img.shape)# 加上噪声
img = img + noise
np.clip(img,0,255)
img = img/255cv2.imshow('Rayleigh noise',img)
cv2.waitKey(0)
print(img.shape)

5、爱尔兰(伽马)噪声

概率密度函数(PDF)如下:(b是一个正整数)

指数分布和卡方分布其实可以看成是伽马分布的特殊形式。

b = 1时:指数分布;

b =n/2,a = 1/2时:卡方分布。

代码:

noise = np.random.gamma(shape=10.0,scale=10.0,size=img.shape)
#其他部分同上

6、均匀噪声

noise = np.random.uniform(50,100,img.shape)
#其他部分同上

二、去噪方法

1、均值滤波

1.1 算术平均滤波

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 算术平均滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = img1[channel][i:i+m,j:j+n].sum()/(m*n)
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('average',rec_img)
cv2.waitKey(0)

具体过程可以配合下图理解

去噪效果:

1.2 几何均值滤波

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 几何均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = np.power(np.prod(img1[channel][i:i+m,j:j+n]),1/(m*n))
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('average',rec_img)
cv2.waitKey(0)

去噪效果:

几何均值滤波对0值是非常敏感,缺陷也很明显,那就是当窗口内像素只要有一个值为0,则其计算得到的值就是0。

1.3 谐波平均滤波

rec_img[channel][i,j] = 1/(np.power(img1[channel][i:i+m,j:j+n],-1).sum())*(m*n)
# 其余部分同上

该方法既能处理盐粒噪声,又能处理类似于于高斯噪声的其他噪声,但是不能处理胡椒噪声

2、统计排序滤波

2.1 中值滤波

我们非常熟悉的一种去噪方法,它是用像素邻域中的灰度中值来代替像素的值。

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 中值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3   #定义滤波核大小
n = 3
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):rec_img[channel][i,j] = np.median(img1[channel][i:i+m,j:j+n])
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('median',rec_img)
cv2.waitKey(0)

去噪效果:

或者直接使用cv2.medianBlur()函数

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = np.uint8(img)# 中值滤波
rec_img = cv2.medianBlur(img,3)cv2.imshow('median',rec_img)
cv2.waitKey(0)

2.2 最大值和最小值滤波

代码:

rec_img[channel][i,j] = (np.amax(img1[channel][i:i+m,j:j+n]) + np.amin(img1[channel][i:i+m,j:j+n]))/2

对高斯噪声处理的滤波效果:

2.4 修正阿尔法均值滤波

处理方法:在邻域 S x y S_{xy} Sxy​ 内删除 d / 2 d/2 d/2个最低灰度值和 d / 2 d/2 d/2个最高灰度值。 g R ( r , c ) g_{R}(r,c) gR​(r,c)表示 S x y S_{xy} Sxy​ 中剩下的 m n − d mn-d mn−d个像素。

d = 0 d=0 d=0: 变成算术平均滤波

d = m n − 1 d=mn-1 d=mn−1:中值滤波

代码:

import cv2
import random
import numpy as np
img = cv2.imread('A.png')# 产生高斯随机数
noise = np.random.normal(0,50,size=img.size).reshape(img.shape[0],img.shape[1],img.shape[2])
# 加上噪声
img = img + noise
img = np.clip(img,0,255)
img = img/255   # 修正阿尔法均值滤波
img1 = np.transpose(img,(2,0,1))  #转换成[channel,H,W]形式
m = 3  #定义滤波核大小
n = 3
d = 4    #d取偶数
rec_img = np.zeros((img1.shape[0],img1.shape[1]-m+1,img1.shape[2]-n+1))
for channel in range(rec_img.shape[0]):for i in range(rec_img[channel].shape[0]):for j in range(rec_img[channel].shape[1]):img2 = np.sort(np.ravel(img1[channel][i:i+m,j:j+n]))  #np.ravel():多维数组变成一维数组rec_img[channel][i,j] = (img2[int(d/2):-int(d/2)].sum())*(1/(m*n-d))
rec_img = np.transpose(rec_img,(1,2,0))cv2.imshow('alpha average',rec_img)
cv2.waitKey(0)

去噪效果:

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

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

相关文章

acwing算法基础之数学知识--求组合数基础版

目录 1 基础知识2 模板3 工程化 1 基础知识 (一) 组合数 C n k C_n^k Cnk​的计算公式, C n k n ⋅ ( n − 1 ) ⋯ ( n − k 1 ) 1 ⋅ 2 ⋯ k C_n^k\frac{n\cdot(n-1)\cdots(n-k1)}{1\cdot 2\cdots k} Cnk​1⋅2⋯kn⋅(n−1)⋯(n−k1)​ …

laravel-admin导出excel全部,表中无id列导出失败

laravel-admin导出excel时,导出全部数据,但是表中没有id字段,然后就无法导出excel; 就直接显示 一开始我也很着急,弄了半天还是不行,然后重写还是有问题 最后发现底层代码排序是按照id排序的orderBy(id, a…

Unity地面交互效果——6、地形动态顶点置换和曲面细分

回到目录 Unity置换贴图局部距离曲面细分 大家好,我是阿赵。   这篇文章是我无聊的时候做了一个demo,觉得挺有趣,于是就发上来。这里面包含了4个内容:置换贴图、顶点偏移、局部曲面细分,曲面细分按距离调整强度。 …

JVS低代码表单设计:数据联动详解(多级数据级、数据回显等)

在这信息化时代,表单作为数据的收集和展示工具,已经渗透到不同的角落。JVS低代码对表单的设计和操作进行了不断的优化和创新。其中,联动回显作为一项重要的功能,无论是多级数据级联控制、组件的联动控制,还是多表的数据…

【0基础学Java第三课】-- 运算符

3. 运算符 3.1 什么是运算符3.2 算术运算符3.2.1 **基本四则运算符:加减乘除模( - * / %)**3.2.2 增量运算符 - * %3.2.3 自增/自减运算符 -- 3.3 关系运算符3.4逻辑运算符(重点)3.4.1 逻辑与 &&3.4.2 逻辑 ||3.4.3逻辑非 !3.4.4 短路求值 3.5 …

DBS note4:Buffer Management

目录 1、介绍 2、缓冲池 3、处理页面请求 4、LRU替换和时钟策略 1)顺序扫描性能 - LRU 5、最近最常使用替换策略(MRU Replacement) 1)Sequential Scanning Performance - MRU 6、练习题 1)判断真假 2&#xf…

华清远见嵌入式学习——网络编程——作业4

作业要求&#xff1a;①使用IO多路复用中的select函数实现TCP并发服务器客户端 ②使用IO多路复用中的poll函数实现TCP并发服务器的服务器端 一、 代码 #include <myhead.h>#define SERPORT 8888 //服务器端口号 #define SERIP "192.168.114.113"…

Samsung下origen中uboot的配置与编译

uboot的特点&#xff1a; n代码结构清晰 n 支持丰富的处理器与开发板&#xff0c;易于移植 n 支持丰富的用户命令 n 支持丰富的网络协议 n 支持丰富的文件系统 n 支持丰富的设备驱动 n 更新活跃、用户较多、资料丰富 n 开放源代码 n 较高的稳定性 n 不具有通用性&#xff08;不…

JavaScript编程基础 – 布尔值(Booleans)

JavaScript编程基础 – 布尔值(Booleans) Javascript Programming Essentials – Booleans 一个JavaScript布尔值包含两个值中的一个&#xff0c;即 true 或者 false。 本文简要介绍JavaScript布尔值的具体应用&#xff0c;以及可能作为对象的布尔值等。 1. 布尔值(Booleans)…

Go语言超全详解(入门级)

文章目录 1. Go语言的出现2. go版本的hello world3. 数据类型3.0 定义变量3.0.1 如果变量没有初始化3.0.2 如果变量没有指定类型3.0.3 :符号3.0.4 多变量声明3.0.5 匿名变量3.0.6 变量作用域 3.1 基本类型3.2 指针3.2.1 指针声明和初始化3.2.2 空指针 3.3 数组3.3.1 声明数组3.…

java+mysql的校园兼职微信小程序(附源码 调试 文档)

校园兼职微信小程序 摘要一、引言二、国内外研究现状三、系统设计四、系统实现与界面展示五、源码获取 摘要 本文详述了一个基于Java和MySQL数据库技术的校园兼职微信小程序的毕业设计。系统主要分为三种用户角色&#xff1a;管理员、学生用户和商家用户。管理员拥有学生管理、…

jjwt使用说明-笔记

jjwt官网链接&#xff1a;https://github.com/jwtk/jjwt POM 依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.12.3</version> </dependency> <dependency><grou…

华纳云:linux中vsz和rss有哪些区别

在Linux中&#xff0c;VSZ(Virtual Set Size)和RSS(Resident Set Size)是两个用于描述进程内存使用的指标&#xff0c;它们表示不同方面的内存情况。 1. VSZ&#xff08;Virtual Set Size&#xff09;: VSZ 表示进程的虚拟内存大小。 包括进程使用的所有内存&#xff0c;包括实…

Python中的函数

一、函数参数与返回值基础知识 1、不要使用可变类型&#xff08;list等&#xff09;作为参数默认值&#xff0c;用None来代替。 参数默认值只会在函数定义阶段被创建一次&#xff0c;之后无论创建多少次&#xff0c;函数内拿到的默认值都是同一个对象&#xff0c;为规避这个问…

Vue 2.0源码分析-数据驱动

Vue.js 一个核心思想是数据驱动。所谓数据驱动&#xff0c;是指视图是由数据驱动生成的&#xff0c;我们对视图的修改&#xff0c;不会直接操作 DOM&#xff0c;而是通过修改数据。它相比我们传统的前端开发&#xff0c;如使用 jQuery 等前端库直接修改 DOM&#xff0c;大大简化…

【python学习】基础篇-常用模块-collections模块:数据结构,如列表、元组、字典和集合等

Python中的collections模块提供了一些有用的数据结构&#xff0c;如列表、元组、字典和集合等。 以下是collections模块中一些常用数据结构的用法&#xff1a; Counter类 Counter类是一个字典子类&#xff0c;用于计数可哈希对象。 它可以接受一个可迭代对象作为参数&#xff…

Atlassian Confluence 路径遍历和命令执行漏洞 (CVE-2019-3396)

漏洞描述 Confluence 是由澳大利亚软件公司 Atlassian 开发的基于 Web 的企业 wiki。 Atlassian Confluence 6.14.2 版本之前存在一个未经授权的目录遍历漏洞&#xff0c;攻击者可以使用 Velocity 模板注入读取任意文件或执行任意命令。 漏洞环境及漏洞利用 启动docker环境…

快来考试拿证书!KubeSphere 个人技能专业考试认证上线啦!

以容器技术和容器编排为基础的云原生应用&#xff0c;被越来越多的企业用户接受和使用&#xff0c;并且在生产环境中使用容器技术的比例逐年增加。Kubernetes 无疑已经成为容器编排的事实基础&#xff0c;而依托于 Kubernetes 开发的开源容器平台 KubeSphere 也收获了一众拥趸。…

vue3使用provider+ inject直接将参数由祖宗传送给孙子

如题。在vue项目中&#xff0c;如果祖宗想将参数传递给孙子甚至更小一辈的组件&#xff0c;是一件麻烦事。可以通过爷爷-儿子-孙子-曾孙这样的链条&#xff0c;一辈辈地传承下去&#xff0c;但未免太繁琐、太蠢了些&#xff1b;也可以通过store间接传送&#xff0c;但如何触发孙…

9-什么是迭代器,生成器,装饰器、django的信号用过吗?如何用,干过什么、什么是深拷贝,什么是浅拷贝,如何使用、slice操作符和list构造函数

1 什么是迭代器&#xff0c;生成器&#xff0c;装饰器 2 django的信号用过吗&#xff1f;如何用&#xff0c;干过什么 3 什么是深拷贝&#xff0c;什么是浅拷贝&#xff0c;如何使用 3.1 浅拷贝 3.2 深拷贝 3.3 扩展(slice操作符和list构造函数) 1 什么是迭代器&#xff0c;生成…