作者|OpenCV-Python Tutorials
編譯|Vincent
來源|OpenCV-Python Tutorials
目標
在本章中,
- 你將學習用于去除影像中噪聲的非區域均值去噪演算法,
- 你將看到不同的函式,例如cv.fastNlMeansDenoising(),cv.fastNlMeansDenoisingColored()等,
理論
在前面的章節中,我們已經看到了許多影像平滑技術,例如高斯模糊,中值模糊等,它們在某種程度上可以消除少量噪聲,在這些技術中,我們在像素周圍采取了一個較小的鄰域,并進行了一些操作,例如高斯加權平均值,值的中位數等來替換中心元素,簡而言之,在像素處去除噪聲是其周圍的區域現象,
有噪聲的性質,
通常認為噪聲是零均值的隨機變數,考慮一個有噪聲的像素,\(p=p_0+n\),其中\(p_0\)是像素的真實值,\(n\)是該像素中的噪聲,你可以從不同的影像中獲取大量相同的像素(例如N)并計算其平均值,理想情況下,由于噪聲的平均值為零,因此應該得到\(p = p_0\),
你可以通過簡單的設定自己進行驗證,將靜態相機固定在某個位置幾秒鐘,這將為你提供很多幀或同一場景的很多影像,然后撰寫一段代碼,找到視頻中所有幀的平均值(這對你現在應該太簡單了),
比較最終結果和第一幀,你會看到噪聲減少,不幸的是,這種簡單的方法對攝像機和場景的運動并不穩健,通常,只有一張嘈雜的影像可用,
因此想法很簡單,我們需要一組相似的影像來平均噪聲,考慮影像中的一個小視窗(例如5x5視窗),
很有可能同一修補程式可能位于影像中的其他位置,有時在它周圍的一個小社區中,一起使用這些相似的補丁并找到它們的平均值怎么辦?對于那個特定的視窗,這很好,請參閱下面的示例圖片:

影像中的藍色補丁看起來很相似,綠色補丁看起來很相似,因此,我們獲取一個像素,在其周圍獲取一個小視窗,在影像中搜索相似的視窗,對所有視窗求平均,然后用得到的結果替換該像素,此方法是“非本地均值消噪”,與我們之前看到的模糊技術相比,它花費了更多時間,但是效果非常好,更多資訊和在線演示可在其他資源的第一個鏈接中找到,
對于彩色影像,影像將轉換為CIELAB色彩空間,然后分別對L和AB分量進行降噪,
OpenCV中的影像去噪
OpenCV提供了此方法的四個變體,
- cv.fastNlMeansDenoising()-處理單個灰度影像
- cv.fastNlMeansDenoisingColored()-處理彩色影像,
- cv.fastNlMeansDenoisingMulti()-處理在短時間內捕獲的影像序列(灰度影像)
- cv.fastNlMeansDenoisingColoredMulti()-與上面相同,但用于彩色影像,
常用引數為:
- h:決定濾波器強度的引數,較高的h值可以更好地消除噪點,但同時也可以消除影像細節,(可以設為10)
- hForColorComponents:與h相同,但僅用于彩色影像,(通常與h相同)
- templateWindowSize:應為奇數,(建議設為7)
- searchWindowSize:應為奇數,(建議設為21)
請訪問其他資源中的第一個鏈接,以獲取有關這些引數的更多詳細資訊,
我們將在此處演示2和3,剩下的留給你,
- cv.fastNlMeansDenoisingColored()
如上所述,它用于消除彩色影像中的噪點,(噪聲可能是高斯的),請參閱以下示例:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('die.png')
dst = cv.fastNlMeansDenoisingColored(img,None,10,10,7,21)
plt.subplot(121),plt.imshow(img)
plt.subplot(122),plt.imshow(dst)
plt.show()
以下是結果的放大版本,我的輸入影像的高斯噪聲為\(σ= 25\),查看結果:

- cv.fastNlMeansDenoisingMulti()
現在,我們將對視頻應用相同的方法,第一個引數是噪聲幀串列,第二個引數imgToDenoiseIndex指定我們需要去噪的幀,為此,我們在輸入串列中傳遞幀的索引,第三是temporalWindowSize,它指定要用于降噪的附近幀的數量,應該很奇怪,在那種情況下,總共使用temporalWindowSize幀,其中中心幀是要被去噪的幀,例如,你傳遞了一個5幀的串列作為輸入,令imgToDenoiseIndex = 2,temporalWindowSize =3,然后使用frame-1,frame-2和frame-3去噪frame-2,讓我們來看一個例子,
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
cap = cv.VideoCapture('vtest.avi')
# 創建5個幀的串列
img = [cap.read()[1] for i in xrange(5)]
# 將所有轉化為灰度
gray = [cv.cvtColor(i, cv.COLOR_BGR2GRAY) for i in img]
# 將所有轉化為float64
gray = [np.float64(i) for i in gray]
# 創建方差為25的噪聲
noise = np.random.randn(*gray[1].shape)*10
# 在影像上添加噪聲
noisy = [i+noise for i in gray]
# 轉化為unit8
noisy = [np.uint8(np.clip(i,0,255)) for i in noisy]
# 對第三幀進行降噪
dst = cv.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)
plt.subplot(131),plt.imshow(gray[2],'gray')
plt.subplot(132),plt.imshow(noisy[2],'gray')
plt.subplot(133),plt.imshow(dst,'gray')
plt.show()

計算需要花費大量時間,結果,第一個影像是原始幀,第二個是噪聲幀,第三個是去噪影像,
附加資源
- http://www.ipol.im/pub/art/2011/bcm_nlm/ (它包含詳細資訊,在線演示等,強烈建議訪問,我們的測驗影像是從此鏈接生成的)
- Online course at coursera (這里拍攝的第一張圖片)
練習
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/31318.html
標籤:其他
上一篇:統計學-統計學方法三要素:策略
