【翻譯:OpenCV-Python教程】影象平滑
⚠️這個系列是自己瞎翻的,文法很醜,主要靠意會,跳著跳著撿重要的部分翻,翻錯了不負責,就這樣哈。
⚠️基於3.4.3,Smoothing Images,附原文。
目標
學會:
- 使用各種低通濾波器模糊影象
- 將定製過濾器應用於影象(2D卷積)
2D卷積(影象過濾)
和一維訊號一樣,影象也可以使用各種低通濾波器(LPF),高通濾波器(HPF)等進行濾波。LPF有助於消除噪聲,模糊影象等等。HPF濾波器有助於找到圖片(中形象)的邊緣。
OpenCV 提供了方法,cv.filter2D() 來把影象和核心做卷積。好像示例一樣,我們會嘗試對影象進行濾波。一個 5x5 平均核心看起來如下:
具體操作是像這樣的:保持這個核心在一個畫素點上,把這個核心覆蓋到的所有的25個畫素加在一起,計算出他們的平均值,並且用這個平均值替換掉中心點的畫素值。它為影象中的每個畫素點重複這個操作。嘗試這段程式碼,檢視結果:
import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('opencv_logo.png') kernel = np.ones((5,5),np.float32)/25 dst = cv.filter2D(img,-1,kernel) plt.subplot(121),plt.imshow(img),plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(dst),plt.title('Averaging') plt.xticks([]), plt.yticks([]) plt.show()
結果:
影象模糊(影象平滑)
通過將影象與低通濾波器核心卷積來實現影象模糊。它用來去除噪音非常有用。它確實從影象中移除了高頻內容(比如:噪音,邊緣)。因此邊緣會在這個操作中被模糊一點,(當然,也有一些不模糊邊緣的模糊技術)OpenCV 提供了provides 主要有四種模糊技術。
1、平均
這種模糊是通過把影象與標準化的盒式濾波器做卷積達成的。它簡單的獲取所有在核心區域之下的所有畫素點的平均值來替代中心元素(的值)。這是由方法 cv.blur() 或者 cv.boxFilter() 來完成的。 檢視文件,瞭解關於核心的更多細節。我們需要指定核心的寬度和高度,一個 3x3 標準化的盒式濾波器看起來應該是下面這樣的:
提示
如果你不想使用標準化的盒式濾波器,用 cv.boxFilter() 。對該方法傳入一個引數 normalize=False 。
檢視以下使用 5x5 大小核心的簡單示例:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('opencv-logo-white.png')
blur = cv.blur(img,(5,5))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()
結果:
2、高斯模糊
在這種模糊中,使用高斯核心代替盒式濾波器。它通過方法 cv.GaussianBlur() 來完成。我們需要指定核心的寬度和高度,它們必須為正奇數。我們還需要分別的指定 X 和 Y 方向的標準差, sigmaX 和 sigmaY 。如果只有 sigmaX 被指定了,sigmaY 就被當做是和 sigmaX 一樣。如果他倆都被指定為0,它們會按照核心大小來計算。高斯模糊在除去影象中的高斯噪聲是非常有效的。
如果你想要的話,你可以通過 cv.getGaussianKernel() 方法建立高斯核心。
之前的程式碼可以被修改為高斯模糊:
blur = cv.GaussianBlur(img,(5,5),0)
結果:
3、中值模糊
這種模糊裡,函式 cv.medianBlur() 取所有核心區域之下的所有畫素的中值來替代中心元素。這對影象中的椒鹽噪聲非常有效。有趣的事情是,在上面那些濾波器裡,中心元素的值都是重新算出來的,也就是說這裡有可能是會算出一個影象中從未出現過的新數值。但中值模糊,中心元素總是會被某個影象中的畫素值替代。它降低了噪音的影響,它的核心應該是一個正的奇數。
在這個示例中,我添加了 50% 的噪音到我們的原圖上,然後應用了中值模糊,看看這結果:
median = cv.medianBlur(img,5)
結果:
4、雙邊濾波器
cv.bilateralFilter() 這個方法在消除噪聲的同事保持邊緣清晰的時候非常有效。但這個操作比起其他的濾波器來更慢。我們已經看到高斯濾波器採用畫素周圍的鄰域並找到其高斯加權平均值。這個高斯濾波器僅僅是一個針對區域的方法,就是說,周圍的畫素點在過濾的時候都被考慮進去了。它沒有考慮這些畫素點是否有相同的亮度,沒有考慮這個畫素點是否是一個邊緣。因此它把邊緣也給模糊了,這不是我們想要的結果。
雙邊濾波器也在區域中採用高斯濾波器的方案,但還引入了一個計算畫素(強度)差的函式。區域中的高斯函式確保僅(過濾器)考慮附近的畫素用於模糊,而這個計算畫素強度差的高斯函式,確保只有那些與中心畫素相似的強度的畫素參與於模糊。因此它保留了邊緣,因為邊緣處的畫素將具有較大的強度變化。
以下示例顯示雙邊濾波器的使用(想知道引數的細節,請檢視文件)。
blur = cv.bilateralFilter(img,9,75,75)
結果:
看,表面上的紋路消失了,但邊緣依然被保留。
額外資源
- 關於雙邊濾波器的細節
- 譯者附:大家還可以瞭解下高斯噪聲和椒鹽噪聲的區別