1. 程式人生 > >[Python影象處理] 四.影象平滑之均值濾波、方框濾波、高斯濾波及中值濾波

[Python影象處理] 四.影象平滑之均值濾波、方框濾波、高斯濾波及中值濾波

該系列文章是講解Python OpenCV影象處理知識,前期主要講解影象入門、OpenCV基礎用法,中期講解影象處理的各種演算法,包括影象銳化運算元、影象增強技術、影象分割等,後期結合深度學習研究影象識別、影象分類應用。希望文章對您有所幫助,如果有不足之處,還請海涵~

本篇文章主要講解Python呼叫OpenCV實現影象平滑,包括四個演算法:均值濾波、方框濾波、高斯濾波和中值濾波。全文均是基礎知識,希望對您有所幫助。知識點如下:
1.影象平滑
2.均值濾波
3.方框濾波
4.高斯濾波
5.中值濾波

PS:本文介紹影象平滑,想讓大家先看看影象處理的效果,後面還會補充一些基礎知識供大家學習。文章參考自己的部落格及網易雲課堂李大洋老師的講解,強烈推薦大家學習。

一.影象平滑

1.影象增強
影象增強是對影象進行處理,使其比原始影象更適合於特定的應用,它需要與實際應用相結合。對於影象的某些特徵如邊緣、輪廓、對比度等,影象增強是進行強調或銳化,以便於顯示、觀察或進一步分析與處理。影象增強的方法是因應用不同而不同的,研究內容包括:(參考課件和左飛的《數字影象處理》)




2.影象平滑
影象平滑是一種區域增強的演算法,平滑演算法有鄰域平均法、中指濾波、邊界保持類濾波等。在影象產生、傳輸和複製過程中,常常會因為多方面原因而被噪聲干擾或出現數據丟失,降低了影象的質量(某一畫素,如果它與周圍畫素點相比有明顯的不同,則該點被噪聲所感染)。這就需要對影象進行一定的增強處理以減小這些缺陷帶來的影響。
簡單平滑-鄰域平均法

3.鄰域平均法


影象簡單平滑是指通過鄰域簡單平均對影象進行平滑處理的方法,用這種方法在一定程度上消除原始影象中的噪聲、降低原始影象對比度的作用。它利用卷積運算對影象鄰域的畫素灰度進行平均,從而達到減小影象中噪聲影響、降低影象對比度的目的。
但鄰域平均值主要缺點是在降低噪聲的同時使影象變得模糊,特別在邊緣和細節處,而且鄰域越大,在去噪能力增強的同時模糊程度越嚴重。



首先給出為影象增加噪聲的程式碼。

# -*- coding:utf-8 -*-
import cv2
import numpy as np

#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
rows, cols, chn = img.shape

#加噪聲
for i in range(5000): x = np.random.randint(0, rows) y = np.random.randint(0, cols) img[x,y,:] = 255 cv2.imshow("noise", img) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()

輸出結果如下所示:



二.均值濾波

1.原理
均值濾波是指任意一點的畫素值,都是周圍N*M個畫素值的均值。例如下圖中,紅色點的畫素值為藍色背景區域畫素值之和除25。




其中紅色區域的畫素值均值濾波處理過程為:
((197+25+106+156+159)+
(149+40+107+5+71)+
(163+198+226+223+156)+
(222+37+68+193+157)+
(42+72+250+41+75)) / 25

其中5*5的矩陣稱為核,針對原始影象內的畫素點,採用核進行處理,得到結果影象。



提取1/25可以將核轉換為如下形式:



2.程式碼
Python呼叫OpenCV實現均值濾波的核心函式如下:
result = cv2.blur(原始影象,核大小)
其中,核大小是以(寬度,高度)表示的元祖形式。常見的形式包括:核大小(3,3)和(5,5)。

(1)K=19[111111111]
(2)K=125[1111111111111111111111111]

程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#讀取圖片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#均值濾波
result = cv2.blur(source, (5,5))

#顯示圖形
titles = ['Source Image', 'Blur Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

輸出結果如下圖所示:



核設定為(10,10)和(20,20)會讓影象變得更加模糊。



如果設定為(1,1)處理結果就是原圖,核中每個權重值相同,稱為均值。

三.方框濾波

方框濾波和均值濾波核基本一致,區別是需不需要均一化處理。OpenCV呼叫boxFilter()函式實現方框濾波。函式如下:
result = cv2.boxFilter(原始影象, 目標影象深度, 核大小, normalize屬性)
其中,目標影象深度是int型別,通常用“-1”表示與原始影象一直;核大小主要包括(3,3)和(5,5),如下所示。

(3)K=19[111111111]
(4)K=125[1111111111111111111111111]

normalize屬性表示是否對目標影象進行歸一化處理。當normalize為true時需要執行均值化處理,當normalize為false時,不進行均值化處理,實際上為求周圍各畫素的和,很容易發生溢位,溢位時均為白色,對應畫素值為255。



在影象簡單平滑中,演算法利用卷積模板逐一處理影象中每個畫素,這一過程可以形象地比作對原始影象的畫素一一進行過濾整理,在影象處理中把鄰域畫素逐一處理的演算法過程稱為濾波器。平滑線性濾波器的工作原理是利用模板對鄰域內畫素灰度進行加權平均,也稱為均值濾波器。



程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#讀取圖片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#方框濾波
result = cv2.boxFilter(source, -1, (5,5), normalize=1)

#顯示圖形
titles = ['Source Image', 'BoxFilter Image']  
images = [source, result]  
for i in xrange(2):  
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

程式碼中使用5*5的核,normalize=1表示進行歸一化處理,此時與均值濾波相同,輸出結果如下圖所示:



下面是影象左上角處理前後的畫素結果:

print(source[0:3, 0:3, 0])
#[[115 180 106]
# [ 83 152  72]
# [ 55  58  55]]
print(result[0:3, 0:3, 0])
#[[92 90 78]
# [92 89 77]
# [82 80 72]]

如果省略引數normalize,則預設是進行歸一化處理。如果normalize=0則不進行歸一化處理,畫素值為周圍畫素之和,影象更多為白色。

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#讀取圖片
img = cv2.imread('test01.png')
source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#方框濾波
result = cv2.boxFilter(source, -1, (5,5), normalize=0)

#顯示圖形
titles = ['Source Image', 'BoxFilter Image']  
images = [source, result]  
for i in xrange(