Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising)

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising)相关的知识,希望对你有一定的参考价值。

Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising)

这篇博客将介绍不同的计算摄影技术——非局部均值去噪(Non-Local Means Denoising),以去除图像中的噪声。OpenCV提供了4个方法实现该算法;

  • cv2.FastNLMeansDeoising() 适用于单个灰度图像
  • cv2.FastNLMeansDeoisingColor() 适用于彩色图像。
  • cv2.fastNlMeansDenoisingMulti() 适用于短时间内捕获的图像序列(灰度图像)
  • cv2.fastNlMeansDenoisingColoredMulti() 适用于短时间内捕获的图像序列(彩色图像)

1. 效果图

原图 VS 彩色图像去噪效果图1如下:

原图 VS 彩色图像去噪效果图2如下:
可以看到去噪的效果图右看起来更加磨皮美白了,颖宝更加动人了。

对彩色图像序列帧进行去噪,原图灰度图 VS 噪音图 VS 去噪效果图1如下:
可能因为图像的原因,看着不是很明显~

对彩色图像序列帧进行去噪,原图灰度图 VS 噪音图 VS 去噪效果图2如下:
用自己的数据集,效果看起来也基本差不多~

2. 原理

  • 前边学习几种图像平滑方法:如高斯模糊,均值模糊,中值模糊,它们在一定程度上很好地去除了少量的噪声。 这些技术在一个像素周围选取一个小邻域,并进行一些操作,如高斯加权平均、值的均值、中值等,以替换中心元素。简言之,像素处的噪声消除是其邻近区域的局部问题。

  • 与之前看到的模糊技术相比,非局部均值去噪需要更多的时间,但效果非常好。

  • 非局部均值去噪需要一组相似的图像来平均噪声。考虑图像中的一个小窗口(比如说5x5窗口)。同一补丁可能在图像中的其他地方的可能性很大。

  • 对于彩色图像,非局部均值去噪将图像转换为CIELAB颜色空间,然后分别对L和AB分量进行去噪。

  • h:决定过滤器强度的参数。较高的h值可以更好地去除噪声,但也可以去除图像的细节(建议10)
  • hForColorComponents:与h相同,但仅适用于彩色图像(通常与h相同)
  • TemplateWindowsSize: 应该是奇数(建议7)
  • SearchWindowsSize: 应该是奇数(建议21)

3. 源码

2.1 单彩色图去噪

# 图像去噪:非局部均值去噪(Non-Local MeansDenoising)

# 前面已经学习了许多图像平滑技术,如高斯模糊、均值模糊、中值模糊等,它们在一定程度上很好地去除了少量的噪声。
# 这些技术在一个像素周围选取一个小邻域,并进行一些操作,如高斯加权平均、值的中值等,以替换中心元素。简言之,像素处的噪声消除是其邻近区域的局部问题。
# 需要一组相似的图像来平均噪声。考虑图像中的一个小窗口(比如说5x5窗口)。同一补丁可能在图像中的其他地方的可能性很大。

# 与之前看到的模糊技术相比,它需要更多的时间,但效果非常好。
# 对于彩色图像,将图像转换为CIELAB颜色空间,然后分别对L和AB分量进行去噪。

# 对单个彩色图像进行去噪
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('images/ml.jpg')

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

plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.xticks([]), plt.yticks([]), plt.title("origin")
plt.subplot(122), plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.xticks([]), plt.yticks([]), plt.title("dst")
plt.show()

2.2 多连续彩色帧去噪

# 对彩色图像序列帧进行去噪
import cv2
import numpy as np
from matplotlib import pyplot as plt

cap = cv2.VideoCapture('images/Megamind.avi')

# 对前5帧创建一个lsit
img = [cap.read()[1] for i in range(5)]

# 均转换为灰度图
gray = [cv2.cvtColor(i, cv2.COLOR_BGR2GRAY) for i in img]

# 转换为float64
gray = [np.float64(i) for i in gray]

# 填充一些噪声点 create a noise of variance 25
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]

# 考虑5帧图像,对第2帧进行去噪,Denoise 3rd frame considering all the 5 frames
dst = cv2.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)

plt.subplot(131), plt.imshow(gray[2], 'gray')
plt.xticks([]), plt.yticks([]), plt.title("origin")

plt.subplot(132), plt.imshow(noisy[2], 'gray')
plt.xticks([]), plt.yticks([]), plt.title("noise")

plt.subplot(133), plt.imshow(dst, 'gray')
plt.xticks([]), plt.yticks([]), plt.title("dst")
plt.show()

参考

以上是关于Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising)的主要内容,如果未能解决你的问题,请参考以下文章

基于相对熵优化VMD的非局部均值去噪方法

NLM非局部均值算法相关

OpenCv 025---图像去噪

[OpenCV-Python] OpenCV 中计算摄影学 部分 IX 对象检测 部分 X

基于非局部滤波图像去噪方法

经典图像去噪算法概述