1. 程式人生 > 其它 >【DW打卡-計算機視覺基礎】04_影象濾波

【DW打卡-計算機視覺基礎】04_影象濾波

4.2 學習目標

  • 瞭解影象濾波的分類和基本概念

  • 理解均值濾波/方框濾波、高斯濾波的原理

  • 掌握OpenCV框架下濾波API的使用

4.4 演算法理論介紹

4.4.1 均值濾波、方框濾波

1. 濾波分類

線性濾波: 對鄰域中的畫素的計算為線性運算時,如利用視窗函式進行平滑加權求和的運算,或者某種卷積運算,都可以稱為線性濾波。常見的線性濾波有:均值濾波、高斯濾波、盒子濾波、拉普拉斯濾波等等,通常線性濾波器之間只是模版係數不同。

非線性濾波: 非線性濾波利用原始影象跟模版之間的一種邏輯關係得到結果,如最值濾波器,中值濾波器。比較常用的有中值濾波器和雙邊濾波器。

2. 方框(盒子)濾波

方框濾波是一種非常有用的線性濾波,也叫盒子濾波,均值濾波就是盒子濾波歸一化的特殊情況。
應用:

可以說,一切需要求某個鄰域內畫素之和的場合,都有方框濾波的用武之地,比如:均值濾波、引導濾波、計算Haar特徵等等。
在原理上,是採用一個卷積核與影象進行卷積.
可見,歸一化了就是均值濾波;不歸一化則可以計算每個畫素鄰域上的各種積分特性,方差、協方差,平方和等等。

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()

輸出效果

你不逼自己一把,你永遠都不知道自己有多優秀!只有經歷了一些事,你才會懂得好好珍惜眼前的時光!