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)的主要内容,如果未能解决你的问题,请参考以下文章