1. 程式人生 > >Python下opencv使用筆記(五)(影象的平滑與濾波)

Python下opencv使用筆記(五)(影象的平滑與濾波)

對於圖形的平滑與濾波,但從濾波角度來講,一般主要的目的都是為了實現對影象噪聲的消除,增強影象的效果。
首先介紹二維卷積運算,影象的濾波可以看成是濾波模板與原始影象對應部分的的卷積運算。關於卷積運算,找到幾篇相關的部落格:

對於2D影象可以進行低通或者高通濾波操作,低通濾波(LPF)有利於去噪,模糊影象,高通濾波(HPF)有利於找到影象邊界。

(一)統一的2D濾波器cv2.filter2D

Opencv提供的一個通用的2D濾波函式為cv2.filter2D(),濾波函式的使用需要一個核模板,對影象的濾波操作過程為:將和模板放在影象的一個畫素A上,求與之對應的影象上的每個畫素點的和,核不同,得到的結果不同,而濾波的使用核心也是對於這個核模板的使用,需要注意的是,該濾波函式是單通道運算的,也就是說對於彩色影象的濾波,需要將彩色影象的各個通道提取出來,對各個通道分別濾波才行。
這裡說一個與matlab相似的情況,matlab中也有一個類似的濾波函式imfilter,對於濾波函式的應用其實不只在於濾波,對於許多影象的整體處理上,其實都可以用濾波函式來組合實現,得到更快的效果,相關的介紹間下面這個部落格:

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

img = cv2.imread('flower.jpg',0) #直接讀為灰度影象
img1 = np.float32(img) #轉化數值型別
kernel = np.ones((5,5),np.float32)/25

dst = cv2.filter2D(img1,-1,kernel)
#cv2.filter2D(src,dst,kernel,auchor=(-1,-1))函式:
#輸出影象與輸入影象大小相同
#中間的數為-1,輸出數值格式的相同plt.figure()
plt.subplot(1,2,1),plt.imshow(img1,'gray')#預設彩色,另一種彩色bgr plt.subplot(1,2,2),plt.imshow(dst,'gray')

這裡寫圖片描述
下面介紹的幾種濾波部分可能是將函式cv2.filter2D()具體化,重新規定一個名字而已,貼一個好的部落格參考:

(二)均值濾波

上述生成的5*5核模板其實就是一個均值濾波。而opencv有一個專門的平均濾波模板供使用–歸一化卷積模板,所有的濾波模板都是使卷積框覆蓋區域所有畫素點與模板相乘後得到的值作為中心畫素的值。Opencv中均值模板可以用cv2.blur和cv2.boxFilter,比如一個3*3的模板其實就可以如下表示:

M=19111111111
模板大小是m*n是可以設定的。如果你不想要前面的1/9,可以使用非歸一化的模板cv2.boxFilter。一個例項如下:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0) #直接讀為灰度影象
blur = cv2.blur(img,(3,5))#模板大小3*5
plt.subplot(1,2,1),plt.imshow(img,'gray')#預設彩色,另一種彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray')

這裡寫圖片描述

(三)高斯模糊模板

現在把卷積模板中的值換一下,不是全1了,換成一組符合高斯分佈的數值放在模板裡面,比如這時中間的數值最大,往兩邊走越來越小,構造一個小的高斯包。實現的函式為cv2.GaussianBlur()。對於高斯模板,我們需要制定的是高斯核的高和寬(奇數),沿x與y方向的標準差(如果只給x,y=x,如果都給0,那麼函式會自己計算)。高斯核可以有效的出去影象的高斯噪聲。當然也可以自己構造高斯核,相關函式:cv2.GaussianKernel().

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

img = cv2.imread('flower.jpg',0) #直接讀為灰度影象
for i in range(2000): #新增點噪聲
    temp_x = np.random.randint(0,img.shape[0])
    temp_y = np.random.randint(0,img.shape[1])
    img[temp_x][temp_y] = 255
blur = cv2.GaussianBlur(img,(5,5),0)
plt.subplot(1,2,1),plt.imshow(img,'gray')#預設彩色,另一種彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray') 

這裡寫圖片描述

(四)中值濾波模板

中值濾波模板就是用卷積框中畫素的中值代替中心值,達到去噪聲的目的。這個模板一般用於去除椒鹽噪聲。前面的濾波器都是用計算得到的一個新值來取代中心畫素的值,而中值濾波是用中心畫素周圍(也可以使他本身)的值來取代他,卷積核的大小也是個奇數。

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

img = cv2.imread('flower.jpg',0) #直接讀為灰度影象
for i in range(2000): #新增點噪聲
    temp_x = np.random.randint(0,img.shape[0])
    temp_y = np.random.randint(0,img.shape[1])
    img[temp_x][temp_y] = 255

blur = cv2.medianBlur(img,5)
plt.subplot(1,2,1),plt.imshow(img,'gray')#預設彩色,另一種彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray') 

這裡寫圖片描述
可以看到中值濾波對於這些白點噪聲的去除是非常的好的。

(五)雙邊濾波

雙邊濾波函式為cv2.bilateralFilter()。該濾波器可以在保證邊界清晰的情況下有效的去掉噪聲。它的構造比較複雜,即考慮了影象的空間關係,也考慮影象的灰度關係。雙邊濾波同時使用了空間高斯權重和灰度相似性高斯權重,確保了邊界不會被模糊掉。有一個介紹專門介紹雙邊濾波的部落格:

cv2.bilateralFilter(img,d,’p1’,’p2’)函式有四個引數需要,d是領域的直徑,後面兩個引數是空間高斯函式標準差和灰度值相似性高斯函式標準差。一個例項如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg',0) #直接讀為灰度影象
for i in range(2000): #新增點噪聲
    temp_x = np.random.randint(0,img.shape[0])
    temp_y = np.random.randint(0,img.shape[1])
    img[temp_x][temp_y] = 255

#9---濾波領域直徑
#後面兩個數字:空間高斯函式標準差,灰度值相似性標準差
blur = cv2.bilateralFilter(img,9,75,75)
plt.subplot(1,2,1),plt.imshow(img,'gray')#預設彩色,另一種彩色bgr
plt.subplot(1,2,2),plt.imshow(blur,'gray')

這裡寫圖片描述