【DW打卡-計算機視覺基礎】04_影象濾波
4.2 學習目標
-
瞭解影象濾波的分類和基本概念
-
理解均值濾波/方框濾波、高斯濾波的原理
-
掌握OpenCV框架下濾波API的使用
4.4 演算法理論介紹
4.4.1 均值濾波、方框濾波
1. 濾波分類
線性濾波: 對鄰域中的畫素的計算為線性運算時,如利用視窗函式進行平滑加權求和的運算,或者某種卷積運算,都可以稱為線性濾波。常見的線性濾波有:均值濾波、高斯濾波、盒子濾波、拉普拉斯濾波等等,通常線性濾波器之間只是模版係數不同。
非線性濾波: 非線性濾波利用原始影象跟模版之間的一種邏輯關係得到結果,如最值濾波器,中值濾波器。比較常用的有中值濾波器和雙邊濾波器。
2. 方框(盒子)濾波
方框濾波是一種非常有用的線性濾波,也叫盒子濾波,均值濾波就是盒子濾波歸一化的特殊情況。
應用:
在原理上,是採用一個卷積核與影象進行卷積.
可見,歸一化了就是均值濾波;不歸一化則可以計算每個畫素鄰域上的各種積分特性,方差、協方差,平方和等等。
3. 均值濾波
均值濾波的應用場合:
根據岡薩雷斯書中的描述,均值模糊可以模糊影象以便得到感興趣物體的粗略描述,也就是說,去除影象中的不相關細節,其中“不相關”是指與濾波器模板尺寸相比較小的畫素區域,從而對影象有一個整體的認知。即為了對感興趣的物體得到一個大致的整體的描述而模糊一幅影象,忽略細小的細節。
均值濾波的缺陷:
均值濾波本身存在著固有的缺陷,即它不能很好地保護影象細節,在影象去噪的同時也破壞了影象的細節部分,從而使影象變得模糊,不能很好地去除噪聲點。特別是椒鹽噪聲。
均值濾波是上述方框濾波的特殊情況,均值濾波方法是:對待處理的當前畫素,選擇一個模板,該模板為其鄰近的若干個畫素組成,用模板的均值(方框濾波歸一化)來替代原畫素的值。公式表示為:
4.4.1 高斯濾波
應用: 高斯濾波是一種線性平滑濾波器,對於服從正態分佈的噪聲有很好的抑制作用。在實際場景中,我們通常會假定影象包含的噪聲為高斯白噪聲,所以在許多實際應用的預處理部分,都會採用高斯濾波抑制噪聲,如傳統車牌識別等。
高斯濾波和均值濾波一樣,都是利用一個掩膜和影象進行卷積求解。不同之處在於:均值濾波器的模板係數都是相同的為1,而高斯濾波器的模板係數,則隨著距離模板中心的增大而係數減小(服從二維高斯分佈)。所以,高斯濾波器相比於均值濾波器對影象個模糊程度較小,更能夠保持影象的整體細節。
二維高斯分佈
高斯分佈公式終於要出場了!
"""
"""
原文連結 https://www.cnblogs.com/sunblingbling/p/12596051.html
"""
程式碼
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
#均值濾波
def blur(source):
img = cv2.blur(source, (10,10))
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲存順序不同
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg) # 圖片上列印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 引數1:字型檔案路徑,引數2:字型大小
draw.text((0, 0), "均值濾波", (255, 0, 0), font=font) # 引數1:列印座標,引數2:文字,引數3:字型顏色,引數4:字型
# PIL圖片轉cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.imshow("blur", cv2charimg)
#中值濾波
def medianBlur(source):
img= cv2.medianBlur(source, 3)
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲存順序不同
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg) # 圖片上列印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 引數1:字型檔案路徑,引數2:字型大小
draw.text((0, 0), "中值濾波", (255, 0, 0), font=font) # 引數1:列印座標,引數2:文字,引數3:字型顏色,引數4:字型
# PIL圖片轉cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.imshow("medianBlur", cv2charimg)
#方框濾波
def BoxFilter(source):
img = cv2.boxFilter(source, -1, (5,5), normalize=1)
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲存順序不同
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg) # 圖片上列印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 引數1:字型檔案路徑,引數2:字型大小
draw.text((0, 0), "方框濾波", (255, 0, 0), font=font) # 引數1:列印座標,引數2:文字,引數3:字型顏色,引數4:字型
# PIL圖片轉cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.imshow("boxFilter", cv2charimg)
#高斯濾波
def GaussianBlur(source):
img = cv2.GaussianBlur(source, (3,3), 0)
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲存順序不同
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg) # 圖片上列印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 引數1:字型檔案路徑,引數2:字型大小
draw.text((0, 0), "高斯濾波", (255, 0, 0), font=font) # 引數1:列印座標,引數2:文字,引數3:字型顏色,引數4:字型
# PIL圖片轉cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.imshow("GaussianBlur", cv2charimg)
#高斯邊緣檢測
def GaussianSideDetect(source):
sobelX = cv2.Sobel(source,cv2.CV_64F,1,0)#x方向的梯度
sobelY = cv2.Sobel(source,cv2.CV_64F,0,1)#y方向的梯度
sobelX = np.uint8(np.absolute(sobelX))#x方向梯度的絕對值
sobelY = np.uint8(np.absolute(sobelY))#y方向梯度的絕對值
img = cv2.bitwise_or(sobelX,sobelY)#
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中顏色的hex碼的儲存順序不同
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg) # 圖片上列印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 引數1:字型檔案路徑,引數2:字型大小
draw.text((0, 0), "高斯邊緣檢測", "green", font=font) # 引數1:列印座標,引數2:文字,引數3:字型顏色,引數4:字型
# PIL圖片轉cv2 圖片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.imshow("GaussianSideDetect", cv2charimg)
if __name__ == '__main__':
img = cv2.imread('./00_dog.jpg', cv2.IMREAD_UNCHANGED)
cv2.imshow("img", img)
blur(img)
medianBlur(img)
BoxFilter(img)
GaussianBlur(img)
GaussianSideDetect(img)
cv2.waitKey(0)
cv2.destroyAllWindows()