OpenCV學習筆記(8)——圖像平滑


  • 使用不同的低筒濾波器對圖像進行模糊
  • 使用自定義的率弄起對圖像進行卷積(2D卷積)

2D卷積

  與信號一樣,我們也可以對2D圖像實施低通濾波,高通濾波等。LPF幫助我們去除噪聲,模糊圖像。而HPF幫助我們找到圖像邊緣。

  OpenCV提供的函數cv2.filter2D()可以讓我們對一幅圖像進行卷積操作。比如下面我們將對一幅圖像使用平均濾波器,如一個5*5的平均濾波器核:

  

操作如下:將核放在圖像的一個像素A上,求與核對應的圖像上的25個像素的和,再取平均數,用這個平均數代替像素A的值。重復以上操作直到將圖像的每一個像素值都更新一邊。例程如下:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('2.jpg')

kernel = np.ones((5,5),np.float32)/25

#cv2.filter2D(src,depth,kernel,...)
#那個depth暫時沒看出有啥用,試了幾個值都沒區別
dst = cv2.filter2D(img,-1,kernel)

cv2.imshow('ori',img)
cv2.imshow('avr',dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

  ---> 

 

圖像模糊(圖像平滑)

   使用低通濾波器可以達到圖像模糊的目的。這對去除噪聲很有幫助。其實就是去掉圖像中的高頻部分(比如:噪聲,邊界)。所以邊界也會被模糊一點(當然也存在一些不會模糊掉邊界的技術)。OpenCV中提供了四種模糊技術。

1.平均

  其實和前面是一樣的,但是實現方法不一樣,他是用卷積框覆蓋區域所有像素的平均值來代替中心元素。可以使用cv2.blur() 和 cv2.boxFilter()來完成。我們需要設定卷積框的寬和高。如下面一個3*3的歸一化卷積框:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('2.jpg')

blur = cv2.blur(img,(3,3))如果改為5*5應該會得到和前面一樣的效果
#如果不想用歸一化卷積框,可以用blur = cv2.boxFilter(src,depth,size,...)並傳入參數normalize=False

#由於用plt讀入BGR圖會出問題,所以改用cv2
cv2.imshow('ori',img)
cv2.imshow('avr',blur)

cv2.waitKey(0)
cv2.destroyAllWindows()

2.高斯模糊

  現在把卷積核換成高斯核(簡單來說,方框不變,原來每個方框里的值是相等的,現在變成高斯分布的,方框中心的值最大,其余方框根據距離中心元素的距離遞減,構成一個高斯小山包。這樣原來的求平均變成了加權平均,權值就是框里的值)。實現的函數是cv2.GaussianBlur()。我們需要制定高斯核的寬和高(必須是奇數)。以及高斯函數眼X,Y方向的標准差。如果我們只指定了X方向的標准差,Y方向也會取相同值。如果兩個標准差均為0,那么函數會根據核函數的大小自己計算。高斯濾波可以有效的從圖像中去除高斯噪聲。

  也可以用cv2.getGaussianKernel()自己構建一個高斯核。

  可以將高斯模糊應用於開始的例子中:

  # -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('2.jpg')

blur = cv2.GaussianBlur(img,(5,5),0)

#由於用plt讀入BGR圖會出問題,所以改用cv2
cv2.imshow('ori',img)
cv2.imshow('avr',blur)

cv2.waitKey(0)
cv2.destroyAllWindows()

 效果如下

   --->

3.中值模糊

  顧名思義就是用與卷積框對應像素的中值來替代中心像素的值。這個濾波器經常用來去除椒鹽噪聲。前面的濾波器都是用計算得到的一個新值來取代中心像素的值,而中值濾波是用中心像素周圍的值來取代他。他能有效的去除噪聲,卷積核的大小也必須是一個奇數(否則哪來的中心)

  我們可以在原圖上加上50%的噪聲在使用中值模糊。

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('6.jpg')

blur = cv2.medianBlur(img,5)

#由於用plt讀入BGR圖會出問題,所以改用cv2
cv2.imshow('ori',img)
cv2.imshow('avr',blur)

cv2.waitKey(0)
cv2.destroyAllWindows()

   --->

 

 4.雙邊濾波

  cv2.bilateralFilter()能在保持邊界清晰的情況下有效的去除噪聲。但是這種操作與其他濾波器相比會比較慢。雙邊濾波和前述的濾波不同,他同時使用空間高斯權重和灰度值相似性高斯權重。空間高斯函數確保只有鄰近區域的像素對中心點有影響,灰度值相似性高斯函數確保只有與中心像素灰度值相近的才會被用來模糊運算。所以這種方法會確保邊界不會被模糊掉,因為邊界處的灰度值變化比較大。

  進行雙邊濾波的代碼如下:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('2.jpg')

#cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace),d是鄰域直徑,兩個75分別し空間高斯函數標准差,灰度值相似性高斯函數標准差
blur = cv2.bilateralFilter(img,9,75,75)

#由於用plt讀入BGR圖會出問題,所以改用cv2
cv2.imshow('ori',img)
cv2.imshow('avr',blur)

cv2.waitKey(0)
cv2.destroyAllWindows()

效果如下:

---> 

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM