【OpenCV-Python】教程:8-1 图像去噪 Image Denoising

OpenCV Python 图像去噪 Image Denoising

【目标】

  • 非局部均值去噪算法去除图像中的噪声。

【理论】

在前面的章节中,我们已经看到了许多图像平滑技术,如高斯模糊,中值模糊等,它们在一定程度上很好地去除少量的噪声。在这些技术中,我们在像素周围取一个小的邻域,并进行一些操作,如高斯加权平均,值的中值等来替换中心元素。简而言之,一个像素的噪声去除是局部的。

噪声有一个特性。噪声通常被认为是一个均值为零的随机变量。考虑一个有噪声的像素, p = p 0 + n p=p_0+n p=p0+n,其中 p 0 p_0 p0是像素的真实值, n n n是像素中的噪声。您可以从不同的图像中获取大量相同的像素(例如 N N N)并计算它们的平均值。理想情况下,你应该得到 p = p 0 p=p_0 p=p0,因为噪声的均值为零。

您可以通过一个简单的设置自己验证它。将静态相机固定在某个位置几秒钟。这将为您提供大量的帧,或同一场景的大量图像。然后写一段代码来找到视频中所有帧的平均值(这对你来说应该太简单了)。比较最终结果和第一帧。你可以看到噪音减少了。不幸的是,这种简单的方法对相机和场景运动不健壮。通常只有一个噪点图像可用。

想法很简单,我们需要一组相似的图像来平均噪声。考虑图像中的一个小窗口(比如5x5窗口)。同样的补丁很有可能出现在图像中的其他地方。有时在它周围的一个小社区。把这些相似的补丁放在一起并找出它们的平均值怎么样?对于特定的窗口,这是可以的。请看下面的示例图片:

在这里插入图片描述

图中的蓝色斑块看起来很相似。绿色的斑块看起来很相似。所以我们取一个像素,在它周围取一个小窗口,在图像中搜索相似的窗口,平均所有的窗口,然后用我们得到的结果替换像素。这种方法是非局部均值去噪。与我们之前看到的模糊技术相比,它需要更多的时间,但它的结果非常好。更多细节和在线演示可以在附加资源的第一个链接中找到。

对于彩色图像,将图像转换为CIELAB色彩空间,然后分别去噪L分量和AB分量。

现在我们将同样的方法应用到视频中。第一个参数是噪声帧的列表。第二个参数imgToDenoiseIndex指定我们需要去噪的帧,为此我们将帧的索引传递到输入列表中。第三个是temporalWindowSize,它指定用于去噪的附近帧的数量。它应该是奇数。在这种情况下,总共使用了temporalWindowSize帧,其中中心帧是要去噪的帧。例如,您传递了一个5帧的列表作为输入。让imgToDenoiseIndex = 2和temporalWindowSize = 3。然后利用帧1、帧2和帧3对帧2进行去噪。

【代码】

在这里插入图片描述

import numpy as np 
import cv2 
from matplotlib import pyplot as plt 

img = cv2.imread("assets/die.png")

dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)

cv2.imshow("src image", img)
cv2.imshow("denoised image", dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

import numpy as np 
import cv2 
from matplotlib import pyplot as plt 

cap = cv2.VideoCapture("assets/vtest.avi")

# 连续读入帧
img = [cap.read()[1] for i in range(5)]

# 转换灰度
gray = [cv2.cvtColor(i, cv2.COLOR_BGR2GRAY) for i in img]
gray = [np.float64(i) for i in gray]
noise = np.random.randn(*gray[1].shape)*10

# 添加噪声到图像中
noisy = [i+noise for i in gray]

# 转换为 uint8
noisy = [np.uint8(np.clip(i, 0, 255)) for i in noisy]

gray_back = [np.uint8(np.clip(i, 0, 255)) for i in gray]

# 参考连续5帧为第3帧降噪
dst = cv2.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)

cv2.imshow("gray", gray_back[2])
cv2.imshow("noisy", noisy[2])
cv2.imshow("dst", dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

【接口】

  • fastNlMeansDenoisingColored
cv2.fastNlMeansDenoisingColored(	src[, dst[, h[, hColor[, templateWindowSize[, searchWindowSize]]]]]	) ->	dst

修改彩色图像的fastnlmeans降噪函数。

  • src: 8位3通道图像
  • dst: 输出结果图像
  • templateWindowSize: 模板 patch 大小,奇数,推荐为7
  • searchWindowSize: 窗口大小(以像素为单位),用于计算给定像素的加权平均。奇数。更大的searchWindowsSize -更长的去噪时间。推荐值21像素
  • h: 亮度组件滤光强度调节参数。较大的h值可以完美地去除噪声,但也可以去除图像细节,较小的h值保留了细节,但也保留了一些噪声
  • hColor: 和h一样,只是颜色分量不同。对于大多数图像,值等于10将足以消除彩色噪声,不扭曲颜色

该函数将图像转换为CIELAB颜色空间,然后使用fastnlmeans降噪函数对给定h参数的L和AB分量分别进行降噪。

  • fastNlMeansDenoisingMulti
cv2.fastNlMeansDenoisingMulti(	srcImgs, imgToDenoiseIndex, temporalWindowSize[, dst[, h[, templateWindowSize[, searchWindowSize]]]]	) ->	dst
cv2.fastNlMeansDenoisingMulti(	srcImgs, imgToDenoiseIndex, temporalWindowSize, h[, dst[, templateWindowSize[, searchWindowSize[, normType]]]]	) ->	dst

利用多帧图像进行降噪

  • srcImgs: 8位,单通道,二通道,三通道,四通道图像序列
  • imgToDenoiseIndex: 需要降噪图像的序号
  • temporalWindowSize: 目标图像周围图像个数
  • dst: 输出与srcImgs图像大小和类型相同的图像。
  • templatewindowsize: 用于计算权重的模板补丁的像素大小。应该是奇数。推荐值7像素
  • searchWindowSize: 窗口大小(以像素为单位),用于计算给定像素的加权平均。应该是奇数。线性影响性能:更大的searchWindowsSize -更长的去噪时间。推荐值21像素
  • h: 参数调节过滤强度。较大的h值可以完美地去除噪声,但也可以去除图像细节,较小的h值保留了细节,但也保留了一些噪声

【参考】

  1. OpenCV: Image Denoising
  2. http://www.ipol.im/pub/art/2011/bcm_nlm/ (It has the details, online demo etc. Highly recommended to visit. Our test image is generated from this link)
  3. Online course at coursera (First image taken from here)
  4. Denoising
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄金旺铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值