图像降噪,也称图像去噪(Image denoising)。
滤波是图像降噪的一种方法,但降噪不是滤波的唯一应用场合。


文章目录

  • 图像噪声
  • 局部去噪
  • 非局部去噪
  • 去噪效果对比


图像噪声


图片降噪python 图片降噪什么意思_彩色图像

原图

常见图像噪声有以下四种:

图片降噪python 图片降噪什么意思_图片降噪python_02

图片降噪python 图片降噪什么意思_彩色图像_03

高斯噪声

泊松噪声

图片降噪python 图片降噪什么意思_ide_04

图片降噪python 图片降噪什么意思_彩色图像_05

乘性噪声

椒盐噪声

高斯噪声

高斯噪声,指概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。

泊松噪声

泊松噪声,指符合泊松分布的噪声模型。泊松分布适合描述单位时间内随机事件发生次数的概率分布。

乘性噪声

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

椒盐噪声

椒盐噪声,又称脉冲噪声,它随机改变一些像素值,是由图像传感器、传输信道、解码处理等产生的黑白相间的亮暗点噪声。

局部去噪

OpenCV中有多个可以降低图像噪声、对图像实现平滑滤波的函数,如

  • blur:对各种噪声都有一定的抑制作用
  • GaussianBlur:对随机噪声比较好,对椒盐噪声效果不好
  • medianBlur:对椒盐噪声效果比较好

具体可参见:图像滤波

非局部去噪

在滤波技术里,通常取像素周围的一小部分邻域进行平滑滤波。对于非局部去噪技术,OpenCV提供了四种变体:

使用单个灰度图像

函数原型:

def fastNlMeansDenoising(src, dst=None, h=None, templateWindowSize=None, searchWindowSize=None)

使用单个彩色图像

函数原型:

def fastNlMeansDenoisingColored(src, dst=None, h=None, hColor=None, templateWindowSize=None, searchWindowSize=None)

通用参数:

  • h:值越大表示去噪声力度越大,同时细节丢失也越多,默认值为10
  • hColor:与h相同,但仅适用于彩色图像,大小通常与h相同
  • templateWindowSize:相似性权重计算窗口大小,一般为5~15之间的奇数
  • searchWindowSize:搜索窗口,大小可以设置为相似性计算窗口大小的3~5倍的奇数

使用在短时间内捕获的图像序列(灰度图像)

函数原型:

def fastNlMeansDenoisingMulti(srcImgs, imgToDenoiseIndex, temporalWindowSize, dst=None, h=None, templateWindowSize=None, searchWindowSize=None)

使用在短时间内捕获的图像序列(彩色图像)

函数原型:

def fastNlMeansDenoisingColoredMulti(srcImgs, imgToDenoiseIndex, temporalWindowSize, dst=None, h=None, hColor=None, templateWindowSize=None, searchWindowSize=None)

通用参数:

  • srcImgs:带噪点的图像帧的列表
  • imgToDenoiseIndex: 指定需要降噪的那一帧对应的索引。
  • temporalWindowSize:指定多少个周围的帧用来去噪,奇数。(如,传入5帧图像列表,imgToDenoiseIndex = 2, temporalWindowSize = 5,即使用第0~4帧,来给第2帧去噪)

去噪效果对比


图片降噪python 图片降噪什么意思_ide_06

import cv2

def get_srcImgs():
	imgs = []
	imgs_gray = []
	videoCapture = cv2.VideoCapture("./test.mp4")
	videoCapture.set(cv2.CAP_PROP_POS_FRAMES, 90) 
	for i in range(3):
		success, img= videoCapture.read()
		gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
		imgs.append(img)
		imgs_gray.append(gray) 
	return imgs, imgs_gray

def show_GaussianBlur(img):
	gaussian = cv2.GaussianBlur(img, (5, 5), 0)
	gaussian_Canny = cv2.Canny(gaussian, 42, 42 * 3, apertureSize=3)
	cv2.imshow('gaussian kSize=5*5', gaussian)
	cv2.imshow('gaussian_Canny', gaussian_Canny)

def denoise(x):
	h = cv2.getTrackbarPos('h', 'denoise demo')
	tempSize = cv2.getTrackbarPos('size', 'denoise demo')
	searchSize = tempSize * 3

	if tempSize % 2 == 0:
		return

	denoise_color = cv2.fastNlMeansDenoisingColored(img, None, h, h, tempSize, searchSize)
	cv2.imshow('denoise color', denoise_color)

	denoise = cv2.fastNlMeansDenoising(gray, None, h, tempSize, searchSize)
	denoise_Canny = cv2.Canny(denoise, 42, 42 * 3, apertureSize=3)
	cv2.imshow('denoise', denoise)
	cv2.imshow('denoise_Canny', denoise_Canny)

	denoise_color_Multi = cv2.fastNlMeansDenoisingColoredMulti(imgs, 1, 3, None, h, h, tempSize, searchSize)
	cv2.imshow('denoise_color_Multi', denoise_color_Multi)

	denoise_Multi = cv2.fastNlMeansDenoisingMulti(imgs_gray, 1, 3, None, h, tempSize, searchSize)
	denoise_Multi_Canny = cv2.Canny(denoise_Multi, 42, 42 * 3, apertureSize=3)
	cv2.imshow('denoise_Multi', denoise_Multi)
	cv2.imshow('denoise_Multi_Canny', denoise_Multi_Canny)

h = 9
size = 9

imgs, imgs_gray = get_srcImgs()
img = cv2.imread("./frame_91.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.namedWindow('denoise demo')
cv2.imshow('denoise demo', img)
cv2.createTrackbar('h', 'denoise demo', h, 30, denoise)
cv2.createTrackbar('size', 'denoise demo', size, 15, denoise)

show_GaussianBlur(img)

denoise(0)
if cv2.waitKey(0) == 27:
	cv2.destroyAllWindows()