文章目錄
- 影像濾波
- 實驗要求
- 實作
- 創建高斯濾波卷積核
- 示例
- 零填充
- 示例
- 代碼
- 結果
影像濾波
實驗要求
實作卷積
基于Python實作函式完成用濾波器h對灰度影像img0進行濾波,回傳
濾波后的影像img1,即
i m g 1 = m y I m a g e F i l t e r ( i m g 0 , h ) img1 = myImageFilter(img0, h) img1=myImageFilter(img0,h)
要求濾波后的影像img1與原始輸入影像具有相同的尺寸,濾波器h每個維
度的大小為奇數(2k + 1, k = 1, 2, · · · ),在進行影像填充的時候可以使用
課堂上講過的任何一種填充方式均可,可以呼叫Python中NumPy的填充函
數,但不能呼叫任何包括convolve, correlate, fftconvolve等函式(僅
可以使用他們來與你自己的實作結果進行對比),函式的實作需采用矢量
化,關于矢量化的例子可參考https://www.pythonlikeyoumeanit.com/
Module3_IntroducingNumpy/VectorizedOperations.html.
(提示:盡可能減少for回圈的個數)
實作
分析步驟:
- 創建高斯濾波卷積核,并做歸一化處理
- 獲取圖片的形狀(高、寬、通道數)
- 圖片零填充處理,得到圖片副本
- 遍歷圖片副本所有像素點,將卷積核與圖片副本的切片進行點乘求和運算,得到輸出圖片
- 輸出圖片切片,恢復原圖形狀
創建高斯濾波卷積核
高斯濾波器將中心像素周圍的像素按照高斯分布加權平均進行平滑化,
按下面的高斯分布公式計算權值:
g
(
x
,
y
,
σ
)
=
1
2
π
σ
2
e
?
x
2
+
y
2
2
σ
2
g(x,y,\sigma) = \frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}
g(x,y,σ)=2πσ21?e?2σ2x2+y2?
并對權值
g
g
g進行歸一化操作,
標準差
σ
\sigma
σ=1.3的8?近鄰高斯濾波器如下:
k
=
1
16
[
1
2
1
2
4
2
1
2
1
]
k = \frac{1}{16} \begin{bmatrix} 1 & 2 &1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \\ \end{bmatrix}
k=161????121?242?121????
示例
def kernal_maker(k_size, sigma):
"""
Create a Gaussian kernel
:param k_size:size of the Gaussian kernal
:param sigma:standard deviation
:return:Gaussian kernal
"""
pad = k_size // 2
k = np.zeros((k_size, k_size), dtype=np.float)
for x in range(-pad, -pad + k_size):
for y in range(-pad, -pad + k_size):
k[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
k /= (2 * np.pi * sigma * sigma)
k /= k.sum()
return k
零填充
由于影像的長寬可能不是濾波器大小的整數倍,因此我們需要在影像的邊緣補0,
示例
# Zero padding
k_size = k.shape[0]
pad = k_size // 2
out = np.zeros((h + pad * 2, w + pad * 2, c), dtype=np.float)
out[pad: pad + h, pad: pad + w] = img0.copy().astype(np.float)
代碼
import numpy as np
import cv2 as cv
def myImageFilter(img0, k):
# YOUR CODE HERE
"""
Fltering using a given kernel k
:param img0:image
:param k: kernal
:return:filtered image
"""
if len(img0.shape) == 3:
h, w, c = img0.shape
else:
img0 = np.expand_dims(img0, axis=-1)
h, w, c = img0.shape
# Zero padding
k_size = k.shape[0]
pad = k_size // 2
out = np.zeros((h + pad * 2, w + pad * 2, c), dtype=np.float)
out[pad: pad + h, pad: pad + w] = img0.copy().astype(np.float)
# filtering
tmp = out.copy()
for y in range(h):
for x in range(w):
for i in range(c):
out[pad + y, pad + x, i] = np.sum(k * tmp[y: y + k_size, x: x + k_size, i])
out = np.clip(out, 0, 255)
out = out[pad: pad + h, pad: pad + w].astype(np.uint8)
return out
def kernal_maker(k_size, sigma):
"""
Create a Gaussian kernel
:param k_size:size of the Gaussian kernal
:param sigma:standard deviation
:return:Gaussian kernal
"""
pad = k_size // 2
k = np.zeros((k_size, k_size), dtype=np.float)
for x in range(-pad, -pad + k_size):
for y in range(-pad, -pad + k_size):
k[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
k /= (2 * np.pi * sigma * sigma)
k /= k.sum()
return k
if __name__ == '__main__':
# Read image
# image = cv.imread("../image/example.png")
image = cv.imread("../image/example_gray.png")
cv.imshow("input", image)
# Create Gaussian kernel
kernal = kernal_maker(k_size=3, sigma=1.3)
# Gaussian Filter
image_filtered = myImageFilter(img0=image, k=kernal)
# Save result
# cv.imwrite("out.jpg", image_processed)
cv.imshow("output", image_filtered)
cv.waitKey(0)
cv.destroyAllWindows()
結果
input

output

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/312256.html
標籤:其他
上一篇:Reactexpressjwt,在哪里呼叫api來檢查用戶是否登錄
下一篇:每個用戶專用的MySql表
