其他分享
首页 > 其他分享> > OpenCV53:图像去噪|Image Denoising

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窗口), 很有可能同一图像块可能位于图像中的其他位置,一起使用这些相似的补丁并找到它们的平均值。参考下面的示例图片:

nlm_patch.jpg

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

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

OpenCV中的图像去噪

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

常用参数为:

例子

cv2.fastNlMeansDenoising()

处理灰度图

在这里插入图片描述

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()

在这里插入图片描述

cv2.fastNlMeansDenoisingColored()

处理彩色图
在这里插入图片描述
如上所述,它用于消除彩色图像中的噪点(噪声可能是高斯的)。请参阅以下示例:

# 彩色图

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()

在这里插入图片描述

cv2.fastNlMeansDenoisingMulti()

处理短时间内捕获的灰度图像序列
在这里插入图片描述

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

例子

# 连续灰度图
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()

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

在这里插入图片描述

放大看下细节部分:
在这里插入图片描述

cv2.fastNlMeansDenoisingColoredMulti()

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

在这里插入图片描述

# 连续彩色图
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()

在这里插入图片描述

附加资源

标签:图像去噪,plt,img,Denoising,OpenCV53,cv2,图像,np,import
来源: https://blog.csdn.net/uncle_ll/article/details/122620346