第7章:图像的平滑处理
第7章:圖像的平滑處理
- 一、均值濾波:
- 二、方框濾波:
- 三、高斯濾波:
- 四、中值濾波
- 五、雙邊濾波:
- 六、2D卷積
? 圖像的平滑處理是在盡量圖像原有信息的情況下,過濾掉圖像內部的噪聲。由于圖像平滑處理的同時通常伴隨著圖像的模糊操作,有時圖像平滑處理也稱為圖像模糊處理。在計算機中有時也被成為圖像濾波。這只是一個名稱,不同的地方可能有不同的說法,不要太過于糾結。
- 圖像平滑處理的目的是:過濾掉圖像內部噪聲
? 圖像平滑處理的實質:是將圖像中與周圍像素點的像素值差異較大的進行處理,將其值調整為周圍像素點像素值的近似值。
如圖所示:
位于第3行第3列的像素點,與周圍像素點值的大小存在明顯差異。反映在圖像上,該點周圍的像素點都是灰度點,而該點的顏色較深,是一個黑色點可能是噪聲,需要將該點的值調整為周圍像素值的近似值。
圖像平滑處理的方式有很多,下面主要介紹:
- 均值濾波
- 方框濾波
- 高斯濾波
- 中值濾波
- 雙邊濾波
- 2D卷積(自定義濾波)
一、均值濾波:
? 均值濾波是指以當前像素點為中心,使用當前像素點周圍N * N個像素值的均值來代替當前像素值。使用該方法遍歷處理圖像內每一個像素點,既可以完成整幅圖像的均值濾波。
? 針對圖像邊緣像素點,可以只取圖像內存在的周圍鄰域點的像素值的均值。也可以將圖像邊緣擴展后,可以在新增的行和列內填充不同的像素值,在此基礎上,再針對原始圖像進行N · N鄰域像素點的均值計算。OpenCV提供了多種邊界處理方式,我們可以根據實際需要選用不同的邊界處理模式。
1、函數語法:
-
在OpenCV中,實現均值的函數是cv2.blur(),其語法格式:
-
dst = cv2.blur(src, ksize, anchor, borderType)
-
dst:返回值,均值濾波處理后得到的處理結果。
-
src:需要處理的圖像,即原始圖像。可以有任意數量的通道,并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
-
ksize:是濾波核的大小。濾波核大小指在均值處理過程中,其鄰域圖像的高度和寬度。例如,其值可以是(5, 5),表示以5×5大小的鄰域均值作為圖像均值濾波處理的結果。
M和N分別對應高度和寬度。一般情況下,M和N是相等的,例如比較常用的3×3、5×5、7×7等。如果M和N的值越大,參與運算的像素點數量就越多,圖像失真越嚴重。
-
anchor:錨點,其默認值是(-1,-1), 表示當前計算均值的點位于核的中心點位置,該值使用默認值即可,在特殊情況下可以指定不同的點作為錨點。
-
borderType:邊界樣式,該值決定了以何種方式來處理邊界,一般情況下不需要考慮該值的取值,采用默認情況即可。
-
-
示例:
import cv2img = cv2.imread('../lena512color_noise.tiff') dst1 = cv2.blur(img, (7, 7)) dst2 = cv2.blur(img, (15, 15)) cv2.imshow('img', img) cv2.imshow('dst1', dst1) cv2.imshow('dst2', dst2) cv2.waitKey() cv2.destroyAllWindows()二、方框濾波:
? 方框濾波與均值濾波不同,方框濾波不會計算像素均值。在均值濾波中,濾波結果是任意一點的鄰域平均值。方框濾波可以自由選擇對均值濾波的結果是否進行歸一化,既可以自由選擇濾波結構是鄰域之和,還是鄰域之和的平均值。
1. 方框濾波語法:
在OpenCV中,實現方框濾波的函數是cv2.boxFilter(),其語法格式是:
dst = cv2.boxFilter(src, ddepth, ksize, anchor, normalize, borderType)
-
dst:返回值,均值濾波處理后得到的處理結果。
-
src:需要處理的圖像,即原始圖像??梢杂腥我鈹盗康耐ǖ?#xff0c;并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
-
ddepth:結果圖像的圖像深度,一般使用-1表示與原始圖像使用相同的圖像深度。
-
ksize:是濾波核的大小。濾波核大小指在均值處理過程中,其鄰域圖像的高度和寬度。例如,其值可以是(5, 5),表示以5×5大小的鄰域均值作為圖像均值濾波處理的結果。
-
anchor:錨點,其默認值是(-1,-1), 表示當前計算均值的點位于核的中心點位置,改制使用默認值即可,在特殊情況下可以指定不同的點作為錨點。
-
normalize:表示在濾波時是否進行歸一化處理(歸一化:這里指的是將計算結果規(guī)范到合理的范圍內,即將計算結果規(guī)范到當前像素值范圍內的值)處理。該參數是一個邏輯值。
- 當參數normalize=1時,表示進行歸一化處理,要用鄰域像素值得和處理面積。
- 當參數normalize=0時,表示不需要進行歸一化處理,直接使用鄰域像素值的和。(當和超出255時為255)
通常情況下,針對方框濾波,卷積核可以表示為:
上述對應關系為:
f(n)={1/width?height,normalize=11,normalize=0f(n)= \begin{cases} 1/width·height, & \text{normalize=1}\\ 1,& \text{normalize=0} \end{cases} f(n)={1/width?height,1,?normalize=1normalize=0?
- borderType:邊界樣式,該值決定了以何種方式來處理邊界。
通常情況下,在使用方框濾波函數時,對于參數anchor、normalize、borderType,直接采用默認值即可。
示例:
import cv2img = cv2.imread('../lena512color_noise.tiff') rst = cv2.boxFilter(img, -1, (7, 7)) cv2.imshow('img', img) cv2.imshow('rst', rst) cv2.waitKey() cv2.destroyAllWindows()三、高斯濾波:
? 在均值濾波和方框濾波中,其鄰域內每個像素的權重是相等的。在高斯濾波中,會將離中心點近的權重加大,離中心點遠的權重減小,在此基礎上計算鄰域內各個像素值不同權重的和。
1. 基本原理
-
在高斯濾波中,卷積核的值不在都是1。如圖
-
在高斯濾波中,卷積核的寬度和高度可以不相同,但是他們必須都是奇數。
-
每一種尺寸的卷積核都可以有多種不同形式的權重比例。如圖同樣是5x5的卷積核。
在不同的資料中,卷積核有多種不同的表示方式。它們可能寫在一個表格內,也可能示寫在一個矩陣內。在實際計算中,卷積核是歸一化處理的,這種處理可以表示為小數形式的卷積核,也可以表示為分數形式。沒有經過歸一化處理的卷積核,是為了說明問題用的。嚴格來講,使用沒有進行歸一化處理的卷積核進行濾波,得到的結果往往是錯誤的。
2. 函數語法:
在OpenCV中,實現高斯濾波的函數cv2.GaussianBlur(),該函數的語法格式是:
dst = cv2.GauusianBlur(src, ksize, sigmaX, sigmaY, borderType)
-
dst:返回值,均值濾波處理后得到的處理結果。
-
src:需要處理的圖像,即原始圖像??梢杂腥我鈹盗康耐ǖ?#xff0c;并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
-
ksize:是濾波核的大小。濾波核大小指在均值處理過程中,其鄰域圖像的高度和寬度。但需要注意,濾波核的值必須是奇數。
-
sigmaX:卷積核在水平方向上(X軸方向)的標準差,其控制的是權重比例。
-
sigmaY:卷積核在垂直方向上(Y軸方向)的標準差,如果將該值設置為0,則只采用sigmaX的值;如果sigmaX、sigmaY都是0,則通過ksize.width和ksize.height計算得到:
- sigmaX = 0.3 × [(ksize.width-1) × 0.5-1] + 0.8
- sigmaY = 0.3 × [(ksize.height-1) × 0.5-1] + 0.8
-
borderType:邊界樣式,該值決定了以何種方式來處理邊界。一般情況下,不需要考慮該值,直接采用默認值。
注意:在該函數中sigmaY、borderType是可選參數。sigmaX是必選參數,但是可以將其設置為0,讓函數自己去計算sigmaX的具體值。
? 官方文檔建議顯示的指定ksize、sigmaX、sigmaY三個參數的值,以避免將來參數修改后可能造成的語法錯誤。當然,實際處理中,可以顯示的指定sigmaX、sigmaY為默認值0。因此,函數cv2.GaussianBlur()的常用形式為:
-
dst = cv2.GaussianBlur(src, ksize, 0, 0)
四、中值濾波
? 中值濾波不同于前面的濾波方式,不再采用濾值的方式計算濾波的結果。它采用的是鄰域內所有像素值的中間值來替代當前像素點的像素值。
1. 基本原理:
? 中值濾波會取當前像素點及其周圍臨近像素點(一共有奇數個像素點)的像素值,將其進行排序,然后將位于中間位置的像素值作為當前像素點的像素值。
2. 函數語法:
在OpenCV中,實現中值濾波的函數是cv2.medianBlur(),其語法格式是:
dst = cv2.medianBlur(src, ksize)
-
dst:返回值,均值濾波處理后得到的處理結果。
-
src:需要處理的圖像,即原始圖像。可以有任意數量的通道,并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
-
ksize:是濾波核的大小。濾波核大小指在均值處理過程中,其鄰域圖像的高度和寬度。但需要注意,濾波核的值必須是比1大的奇數, 比如3、5、7等。
示例:
import cv2img = cv2.imread('../lena512color_noise.tiff') rst = cv2.medianBlur(img, 5) cv2.imshow('img', img) cv2.imshow('rst', rst) cv2.waitKey() cv2.destroyAllWindows()? 從結果可以看出,由于沒有進行均值處理,中值濾波不存在均值濾波等濾波方式帶來的細節(jié)模糊問題。在中值濾波處理中,噪聲成分很難被選上,所以可以在幾乎不影響原有圖像的情況下取出全部噪聲。但缺點是由于需要進行排序等操作,中值濾波需要的運算量較大。
五、雙邊濾波:
? 雙邊濾波是綜合考慮空間信息和色彩信息的濾波方式,在濾波過程中能夠有效地保護圖像內的邊緣信息。
1. 基本原理:
前面的濾波方式都只考慮了空間的權重信息,這種情況計算起來比較方便,但在處理邊緣信息時會存在較大問題。例如,圖像左側是黑色,右側是白色,中間是很明顯的邊緣。
? 在均值濾波、方框濾波、高斯濾波中,都會計算邊緣上各個像素點的加權平均值,從而模糊邊緣信息。如下圖是高斯濾波處理過的圖像:
? 雙邊濾波在計算某一像素點的新值時,不僅考慮距離信息(距離越遠,權重越小)還考慮色彩信息(色彩差別越大,權重越小)。雙邊濾波綜合考慮距離和色彩的權重結構,既能有效的去除噪聲,又能夠較好的保護邊緣信息。
? 在雙邊濾波中,當處在邊緣時,與當前點色彩相近的像素點(顏色距離很近)會被給予較大的權重值;而與當前色彩差別較大的像素點(顏色距離很遠)會被給予較小的權重值(極端情況下權重可能為0,直接忽略該點),這樣就保護了邊緣信息。
2. 函數語法:
在OpenCV中,實現雙邊濾波的函數是cv2.bilateralFilter(),該函數的語法是:
dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, borderType)
- dst:返回值,均值濾波處理后得到的處理結果。
- src:需要處理的圖像,即原始圖像。可以有任意數量的通道,并能對各個通道獨立處理。圖像的深度應該是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F中的一種。
- d:在濾波時選取的空間距離參數,這里表示以當前為中心點的直徑。如果該值為非正數,則會自動從參數sigmaSpace計算得到如果濾波空間較大(d>5),則速度較慢。因此,在實際應用中推薦d=5。對于較大噪聲的離線濾波可以選擇d=9。
- sigmaColor:濾波處理時選取的顏色差值范圍,該值決定了周圍哪些像素點能夠參與到濾波中來。與當前像素點的像素值差值小于sigmaColor的像素點,能夠參與到當前的濾波中。該值越大,說明周圍有越多的像素點可以參與到運算。該值為0時,濾波失去意義;該值為255時,指定直徑內所有點都能夠參與運算。
- sigmaSpagce:是坐標空間內的sigma值。它的值越大,說明有越多的點能夠參與到濾波計算中來。當d>0時,無論sigmaSpagce的值如何,d都指定鄰域大小;否則,d與sigmaSpace的值成比例。
- borderType:邊界樣式,該值決定了以何種方式來處理邊界。一般情況下,不需要考慮該值,直接采用默認值。
? 簡單起見的話可以將sigmaColor、sigmaSpagce的值設為相同的。如果他們的值比較小(小于10)濾波效果不明顯;如果他們的值比較大(例如:大于150),則濾波效果會比較明顯,會產生卡通效果。
在cv2.bilateralFilter()函數中,除了borderType為可選參數外,其他均為必選參數。
import cv2img = cv2.imread('../lena512color_noise.tiff') rst = cv2.bilateralFilter(img, 25, 100, 100) cv2.imshow('img', img) cv2.imshow('rst', rst) cv2.waitKey() cv2.destroyAllWindows()由上面結果可以看出,雙邊濾波對去除噪聲的效果并不好。雙邊濾波的優(yōu)勢體現在對邊緣信息的處理上。
import cv2 import numpy as npimg = np.zeros((500, 500), dtype=np.uint8) img[:, :250] = 255 rst = cv2.bilateralFilter(img, 25, 100, 100) cv2.imshow('img', img) cv2.imshow('rst', rst) cv2.waitKey() cv2.destroyAllWindows()六、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:修正值??蛇x項,如果該值存在,會在基礎濾波的結果上加上該值作為最終的濾波處理結果。
-
borderType:邊界樣式,該值決定了以何種方式來處理邊界。一般情況下,不需要考慮該值,直接采用默認值。
通常情況下,使用濾波函數cv2.filter2D()時,對于參數anchor、delta、borderType直接采用默認值即可。
示例: 自定義一個卷積核,通過函數cv2.filter2D()應用該卷積核對圖像進行濾波操作,并顯示濾波結果。
import cv2 import numpy as npimg = cv2.imread('../lena512color_noise.tiff') kernal = np.ones((9, 9), dtype=np.float32) / 81 rst = cv2.filter2D(img, -1, kernal) cv2.imshow('img', img) cv2.imshow('rst', rst) cv2.waitKey() cv2.destroyAllWindows()總結
以上是生活随笔為你收集整理的第7章:图像的平滑处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RS485无线通讯模块工作原理详解
- 下一篇: python-snap7的安装记录