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

news2024/9/24 1:27:30

一、噪声分类

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/255

cv2.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] = 0
    else:
        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/255

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

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

相关文章

简单聊聊加密和加签的关系与区别

大家好,我是G探险者。 平时我们在项目上一定都听过加密和加签,加密可能都好理解,知道它是保障的数据的机密性,那加签是为了保障啥勒?它和加密有啥区别? 带着这个疑问,我们就来聊聊二者的区别。…

【Python】Fastapi swagger-ui.css 、swagger-ui-bundle.js 无法加载,docs无法加载,redocs无法使用

使用fastapi的时候,swagger-ui.css 、swagger-ui-bundle.js、redoc.standalone.js 有时候无法加载(国内环境原因或者是局域网屏蔽),此时就需要自己用魔法下载好对应文件,然后替换到fastapi里面去。 fastapi里面依靠这…

redis运维(十九)redis 的扩展应用 lua(一)

一 redis 的扩展应用 lua redis如何保证原子操作 说明:引入lua脚本,核心解决原子性问题 ① redis为什么引入lua? lua脚本本身体积小,启动速度快 ② redis引入lua的优势 小结: 类似自定义redis命令 ③ redis中如何使用lua ④ EVAL 说明&#…

《算法通关村——数论问题解析》

《算法通关村——数论问题解析》 辗转相除法 辗转相除法又叫做欧几里得算法,是公元前 300 年左右的希腊数学家欧几里得在他的著作《几何原本》提出的。最大公约数(greatest common divisor,简写为gcd),是指几个数的共有的因数之中最大的一个…

csv文件添加文件内容和读取

append content to file import numpy as np acc_listnp.array([0.97,0.92,0.93,0.89]) # 注意这个地方添加文件不需要特别声明是什么文件 file open("result.csv", "a") print("{:.2f}, {:.2f}".format(acc_list.mean(), acc_list.std()), f…

leetcode刷题日志-167.两数之和II-输入有序数组

给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index2 < numbers.…

浏览器没收到返回,后端也没报错,php的json_encode问题bug

今天网站遇到个问题&#xff0c;后端返回异常&#xff0c;但是浏览器状态码200&#xff0c;但是看不到结果。经过排查发现&#xff0c;我们在返回结果的时候使用了json_encode返回给前端&#xff0c;结果里面的字符编码异常&#xff0c;导致json_encode异常&#xff0c;但是php…

ComfyUI搭建使用教程

ComfyUI 是一个基于节点流程式的stable diffusion AI 绘图工具WebUI&#xff0c; 你可以把它想象成集成了stable diffusion功能的substance designer&#xff0c; 通过将stable diffusion的流程拆分成节点&#xff0c;实现了更加精准的工作流定制和完善的可复现性。但节点式的工…

系列二、Spring整合单元测试

一、概述 Spring中获取bean最常见的方式是通过ClassPathXmlApplicationContext 或者 AnnotationConfigApplicationContext的getBean()方式获取bean&#xff0c;那么在Spring中如何像在SpringBoot中直接一个类上添加个SpringBootTest注解&#xff0c;即可在类中注入自己想要测试…

pytest-pytest-html测试报告这样做,学完能涨薪3k

在 pytest 中提供了生成html格式测试报告的插件 pytest-html 安装 安装命令如下&#xff1a; pip install pytest-html使用 我们已经知道执行用例的两种方式&#xff0c;pytest.main()执行和命令行执行&#xff0c;而要使用pytest-html生成报告&#xff0c;只需要在执行时加…

飞翔的小鸟小游戏

主类 package APP;import 框架.GameFrame;public class GameApp {public static void main(String[] args) {//游戏的入口new GameFrame();} }场景实物 package 框架;import 图导.Constant; import 图导.GameUtil;import java.awt.*; import java.awt.image.BufferedImage; …

VR模拟仿真技术为司法科普建设注入更多的智慧和力量

虚拟现实(VR)技术已经逐渐渗透到各个领域&#xff0c;包括司法领域&#xff0c;在法学院教学中&#xff0c;VR虚拟现实和web3d开发技术的兴起&#xff0c;让司法教育也突破传统教授式、演练式的教学模式&#xff0c;通过VR特有的沉浸式展示特点&#xff0c;实现了真实法庭效果的…

飞书如何接入ChatGPT-打造个人智能问答助手实现无障碍交流

目录 前言 环境列表 1.飞书设置 2.克隆feishu-chatgpt项目 3.配置config.yaml文件 4.运行feishu-chatgpt项目 5.安装cpolar内网穿透 6.固定公网地址 7.机器人权限配置 8.创建版本 9.创建测试企业 10. 机器人测试 总结 前言 在飞书中创建chatGPT机器人并且对话&am…

目标检测算法 - YOLOv4

文章目录 1. 简介2. YOLOv4整体结构3. Backbone4. Neck 1. 简介 YOLOv4是YOLOv3的改进版。YOLOv4并不是原YOLO项目的作者。发表于CVPR2020。 改进&#xff1a; 主干特征提取网络&#xff1a;Darknet53 -> CSPDarknet53特征金字塔&#xff1a;SPP&#xff0c;PAN分类回归层…

TikTok shop印尼重启电商征程:与当地平台合作开启新篇章!——站斧浏览器

经历了一个半月的间隔&#xff0c;TikTok Shop成功重返印度尼西亚市场。据国际媒体报道&#xff0c;TikTok计划通过与印尼本地电子商务平台的合作&#xff0c;重启其在该国的电商业务。 Temmy Satya Permana&#xff0c;印尼合作社和中小企业部的官员&#xff0c;证实了这一重…

【LeetCode刷题】--59.螺旋矩阵II

59.螺旋矩阵II class Solution {public int[][] generateMatrix(int n) {int[][] res new int[n][n];int count 1;int left 0,right n-1,top 0,bottom n -1;while(left < right && top < bottom){for(int col left;col < right;col){ //从左往右res[to…

[MySQL] MySQL 表的增删查改

本篇文章对mysql表的增删查改进行了详细的举例说明解释。对表的增删查改简称CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09;。其中重点是对查询select语句进行了详细解释&#xff0c;并且通过多个实际例子来帮助…

leetcode刷题之用栈实现队列(C语言版)

leetcode刷题之用栈实现队列&#xff08;C语言版&#xff09; 一、题目描述二、题目要求三、题目解析Ⅰ、typedef structⅡ、MyQueue* myQueueCreateⅢ、void myQueuePush(MyQueue* obj, int x)Ⅳ、int myQueuePeek(MyQueue* obj)Ⅴ、int myQueuePop(MyQueue* obj)Ⅶ、bool myQ…

Charles 网络抓包工具详解与实战指南

文章目录 导读软件版本Charles基本原理核心功能下载及安装界面介绍网络包展示 常用场景介绍PC 端网络抓包移动端网络抓包PC 端配置手机端配置 开启 SSL 代理PC 端和移动端 CA 证书安装Charles 直接安装Charles 下载 CA 文件手动安装 常用操作请求重发请求改写、动态改写断点&am…

C# Winform使用log4net记录日志

写在前面 Log4Net是从Java的log4j移植过来的&#xff0c;功能也与log4j类似&#xff0c;可以把日志信息输出到文件、数据库、控制台、Windows 事件日志、远程系统日志服务等不同的介质或目标。 Log4Net配置选项丰富灵活&#xff0c;并且可在运行时动态更新配置并应用&#xf…