OpenCV53:图像去噪|Image Denoising

目标

在本章中, 将学习

理论

在前面的章节中,已经看到了许多图像平滑技术,例如高斯模糊、中值模糊等,它们在某种程度上可以消除少量噪声。在这些技术中,都是在像素周围采取了一个较小的邻域,并进行了一些操作,例如高斯加权平均值(高斯模糊)、值的中位数(中值模糊)等来替换中心元素。简而言之,像素处的噪声去除是其邻域的局部。

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

这是可以通过简单的设置进行验证得到的。将静态相机固定在某个位置几秒钟,这会提供很多帧或同一场景的很多图像,然后编写一段代码,找到视频中所有帧的平均值,比较最终结果和第一帧的结果, 会看到噪声减少。不幸的是,这种简单的方法对摄像机和场景的运动并不稳健

上述想法很简单,需要一组相似的图像来平均噪声。考虑图像中的一个小窗口(例如5x5窗口), 很有可能同一图像块可能位于图像中的其他位置,一起使用这些相似的补丁并找到它们的平均值。参考下面的示例图片:

OpenCV53:图像去噪|Image Denoising

图像中的蓝色图像块看起来很相似,图像中的绿色图像块看起来也很相似。因此,过程为:首先获取一个像素,在其周围获取一个小窗口,在图像中搜索相似的窗口,对所有窗口求平均值,然后用得到的结果替换该像素。此方法是**“非本地均值消噪”(Non-Local Means Denoising)**。与之前看到的模糊技术相比,该方法花费更多时间,但是效果非常好。更多信息和在线演示可在此看到

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

OpenCV中的图像去噪

OpenCV提供了此方法的四个变体:

常用参数为:

  • h决定滤波器强度的参数较高的h值可以更好地消除噪点,但同时也可以消除图像细节(可以设为10)

  • hForColorComponents:与h相同,但仅用于彩色图像(通常与h相同)

  • templateWindowSize:应为奇数(建议设为7)

  • searchWindowSize:应为奇数(建议设为21)

例子

cv2.fastNlMeansDenoising()

处理灰度图

OpenCV53:图像去噪|Image Denoising

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

img = cv2.imread('die.png', 0)
dst = cv2.fastNlMeansDenoising(img, None, 10, 7, 21)
plt.subplot(211)
plt.imshow(img)
plt.subplot(212)
plt.imshow(dst)
plt.show()

OpenCV53:图像去噪|Image Denoising

cv2.fastNlMeansDenoisingColored()

处理彩色图
OpenCV53:图像去噪|Image Denoising
如上所述,它用于消除彩色图像中的噪点(噪声可能是高斯的)。请参阅以下示例:

# 彩色图

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

img = cv2.imread('die.png')
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)  # rgb into bgr
dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
plt.subplot(211)
plt.imshow(img)
plt.subplot(212)
plt.imshow(dst)
plt.show()

OpenCV53:图像去噪|Image Denoising

cv2.fastNlMeansDenoisingMulti()

处理短时间内捕获的灰度图像序列
OpenCV53:图像去噪|Image Denoising

将对视频应用相同的方法:

  • 第一个参数是srcImgs, 噪声帧列表, 具有相同的类型和大小
  • 第二个参数是imgToDenoiseIndex,指定需要去噪的帧。为此在输入列表中传递帧的索引
  • 第三个参数是temporalWindowSize ,指定要用于降噪的附近帧的数量,应该设置为奇数。总共使用 temporalWindowSize 帧,其中中心帧是要被去噪的帧。例如,传递一个5帧的列表作为输入,令 i m g T o D e n o i s e I n d e x = 2 imgToDenoiseIndex =2 imgToDenoiseIndex=2,$temporalWindowSize =3 $。然后使用 frame-1frame-2frame-3去噪frame-2

例子

# 连续灰度图
import cv2
import numpy as np
from matplotlib import pyplot as plt

cap = cv2.VideoCapture('vtest.avi')

# create a list of first 5 frames
img = [cap.read()[1] for i in range(5)]

# convert all to grayscale
gray = [cv2.cvtColor(i, cv2.COLOR_BGR2GRAY) for i in img]

# convet all to float64
gray = [np.float64(i) for i in gray]

# create a noise of variance 25
noise = np.random.randn(*gray[1].shape)*10

# Add this noise to images
noisy = [i+noise for i in gray]

# Convert back to uint8
noisy = [np.uint8(np.clip(i, 0, 255)) for i in noisy]

# Denoise 3rd frame considering all the 5 frames
dst = cv2.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 7, 21, 35)

plt.subplot(311)
plt.imshow(gray[2],'gray')
plt.subplot(312)
plt.imshow(noisy[2],'gray')
plt.subplot(313)
plt.imshow(dst,'gray')
plt.show()

计算需要花费大量时间。结果,第一个图像是原始帧,第二个是噪声帧,第三个是去噪图像。

OpenCV53:图像去噪|Image Denoising

放大看下细节部分:
OpenCV53:图像去噪|Image Denoising

cv2.fastNlMeansDenoisingColoredMulti()

处理短时间内捕获的彩色图像序列

OpenCV53:图像去噪|Image Denoising

# 连续彩色图
import cv2
import numpy as np
from matplotlib import pyplot as plt

cap = cv2.VideoCapture('vtest.avi')

# create a list of first 5 frames
img = [cap.read()[1] for i in range(5)]

# convet all to float64
img_64 = [np.float64(i) for i in img]

# create a noise of variance 25
noise = np.random.randn(*img_64[1].shape)*10

# Add this noise to images
noisy = [i+noise for i in img_64]

# Convert back to uint8
noisy = [np.uint8(np.clip(i, 0, 255)) for i in noisy]

# Denoise 3rd frame considering all the 5 frames
dst = cv2.fastNlMeansDenoisingColoredMulti(noisy, 2, 5, None, 7, 21, 35)

plt.subplot(311)
plt.imshow(img[2])
plt.subplot(312)
plt.imshow(noisy[2])
plt.subplot(313)
plt.imshow(dst)
plt.show()

OpenCV53:图像去噪|Image Denoising

附加资源

上一篇:Python 线性回归计算r-squared方法


下一篇:Python:Matplotlib画图示例