引言
在數字圖像處理中,圖像平滑是一項基礎而重要的預處理技術。它主要用于消除圖像中的噪聲、減少細節層次,為后續的圖像分析(如邊緣檢測、目標識別等)創造更好的條件。OpenCV作為最流行的計算機視覺庫之一,提供了多種圖像平滑方法。本文將詳細介紹這些方法及其應用場景。
一、什么是圖像平滑?
圖像平滑(Image Smoothing)是指通過特定的算法對圖像進行模糊處理,從而達到降噪、去除細節或預處理的目的。這種處理雖然會使圖像變得"模糊",但在許多計算機視覺任務中卻能帶來更好的處理效果。
二、常見的圖像平滑方法
1.先對圖片加上噪聲點
import cv2
import numpy as np
def add_peppersalt_noise(image,n=1000):result = image.copy()h,w = image.shape[:2] #獲取圖片的高和寬for i in range(n): #生成n個椒鹽噪聲x = np.random.randint(1,h)y = np.random.randint(1,w)if np.random.randint(0,2) == 0:result[x,y] = 0else:result[x,y] = 255return resultimage = cv2.imread('zhaoyun.jpg')
cv2.imshow('yuantu',image)
cv2.waitKey(0)noise = add_peppersalt_noise(image)
cv2.imshow('noise',noise)
cv2.waitKey(0)
2. 均值濾波(Averaging)
dst=cv2.blur(src,ksize,anchor,borderType)dst是返回值src是需要處理的圖像ksize是濾波核(卷積核)的大小anchor是錨點,默認值是(-1,-1)一般無需更改borderType是邊界樣式,一般無需更改一般情況下,使用dst=cv2.blur(src,ksize)即可
均值濾波是最簡單的線性濾波方法,它用像素點鄰域的平均值來代替該像素點的值。
blur_1 = cv2.blur(noise,(3,3)) #卷積核為3,3 效果一般,清晰度一般
cv2.imshow('blur_1',blur_1)
cv2.waitKey(0)blur_2 = cv2.blur(noise,(5,5)) #卷積核為5,5 效果稍好但模糊
cv2.imshow('blur_2',blur_2)
cv2.waitKey(0)
cv2.destroyAllWindows()
特點:
- 算法簡單,計算速度快
- 對高斯噪聲有較好的效果
- 會導致圖像邊緣模糊
3. 方框濾波(boxFilter)
dst=cv2.boxFilter(src,deepth,ksize,anchor,normalize,borderType)式中:dst是返回值,表示及進行方框濾波后得到的處理結果。src是需要處理的圖像,即原始圖像deepth是處理結果圖像的圖像深度,一般使用-1表示與原始圖像使用相同的圖像深度。(可以理解為數據類型)ksize是濾波核(卷積核)的大小anchor是錨點(指對應哪個區域),默認值是(-1,-1)一般無需更改normalize 表示在濾波時是否進行歸一化。1.當為True時,歸一化,用鄰域像素值的和除以面級。 此時方框濾波與均值濾波效果相同。2.當為False時,不歸一化,直接使用鄰域像素值的和。和>255時使用255。
方框濾波在平滑圖像的同時能很好地保留邊緣信息,結合了空間鄰近度和像素值相似度。
boxFilter_1 = cv2.boxFilter(noise,-1,(3,3),normalize=True)
cv2.imshow('boxFilter_1',boxFilter_1)
cv2.waitKey(0)
boxFilter_2 = cv2.boxFilter(noise,-1,(3,3),normalize=False)
cv2.imshow('boxFilter_2',boxFilter_2)
cv2.waitKey(0)
4. 中值濾波(Median Blur)
中值濾波用鄰域的中值代替中心像素的值,是一種非線性濾波方法。
medianB = cv2.medianBlur(noise,3)
cv2.imshow('medianBlur',medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 特點:
- 對椒鹽噪聲特別有效
- 能較好保留邊緣信息
- 計算量比線性濾波大
5. 高斯濾波(Gaussian Blur)
dst=cv2.GaussianBlur(src,ksize[,sigmaX[,sigmaY[,dst]]]) 高斯濾波
# 參數說明:
# src:輸入圖像,通常是一個NumPy數組
# ksize:濾波器的大小,它是一個元組,表示在水平和垂直方向上的像素數量。例如(5,5)表示一個5×5的濾波器。
# sigmaX和sigmaY:分別表示在X軸和Y軸方向上的標準差。這些值與濾波器大小相同。默認情況下,他們都等于0,這意味著沒有高斯模糊。
# dst:輸出圖像,通常是一個NumPy數組。如果位None,則會創建一個新的數組來存儲結果。
高斯濾波是一種加權平均濾波,離中心點越近的像素權重越大,符合高斯分布。
GaussianB = cv2.GaussianBlur(noise,(3,3),1)
cv2.imshow('GaussianBlur',GaussianB)
cv2.waitKey(0)
特點:
對高斯噪聲有很好的去除效果
比均值濾波更能保留邊緣信息
是許多計算機視覺任務的首選平滑方法
三、方法比較與選擇指南
方法?? ?優點?? ?缺點?? ?適用場景
均值濾波?? ?簡單快速?? ?邊緣模糊嚴重?? ?快速預處理,不關心邊緣
高斯濾波?? ?平滑效果好,計算較快?? ?對椒鹽噪聲效果一般?? ?通用平滑處理,特別是高斯噪聲
中值濾波?? ?對椒鹽噪聲效果好?? ?計算量較大?? ?去除椒鹽噪聲
方框濾波?? ?邊緣保持好?? ?計算復雜度高?? ?需要保留邊緣的去噪
四、總結
圖像平滑是計算機視覺預處理的重要步驟。OpenCV提供了多種平滑方法,各有特點和適用場景。在實際應用中,應根據噪聲類型、邊緣保持需求和計算資源等因素選擇合適的方法。理解這些方法的原理和特點,能夠幫助我們在實際項目中做出更合理的選擇。
希望本文能幫助您更好地理解和應用OpenCV中的圖像平滑技術。在實踐中多嘗試不同的方法和參數,觀察它們的效果差異,這將有助于您掌握這些技術的精髓。
六、2D卷積
? OpenCV提供了多種濾波方式,來是實現平滑圖像的效果,例如均值濾波、方框濾波、高斯濾波、中值濾波等。大多數濾波方式所使用的卷積核都具有一定的靈活性,能夠方便地設置卷積核的大小和數量。但是,我們有時候希望使用特定的卷積核來實現卷積操作,例如使用如下卷積核來進行卷積操作。
前面介紹過的濾波函數都無法將卷積核確定為上述形式,這時要使用OpenCV的自定義卷積函數。
? 在OpenCV中,允許用戶自定義卷積核實現卷積操作,使用自定義卷積核實現卷積操作的函數是cv2.filer2D(),其語法格式為:
dst = cv2.filter2D(src, ddepth, kernel, anchor, delta, borderType)
dst:返回值,均值濾波處理后得到的處理結果。
src:需要處理的圖像,即原始圖像。可以有任意數量的通道,并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
ddepth:結果圖像的圖像深度,一般使用-1表示與原始圖像使用相同的圖像深度。
kenel:卷積核,是一個單通道的數組。如果想在處理彩色圖像時,讓每個通道使用不同的核,則必須將彩色圖像分解后使用不同的核進行操作。
anchor:錨點,其默認值是(-1,-1), 表示當前計算均值的點位于核的中心點位置,改制使用默認值即可,在特殊情況下可以指定不同的點作為錨點。
delta:修正值。可選項,如果該值存在,會在基礎濾波的結果上加上該值作為最終的濾波處理結果。
borderType:邊界樣式,該值決定了以何種方式來處理邊界。一般情況下,不需要考慮該值,直接采用默認值。
通常情況下,使用濾波函數cv2.filter2D()時,對于參數anchor、delta、borderType直接采用默認值即可。
示例: 自定義一個卷積核,通過函數cv2.filter2D()應用該卷積核對圖像進行濾波操作,并顯示濾波結果。