MATLAB、Python、Scilab、Julia比較ページはこちら
https://www.simulationroom999.com/blog/comparison-of-matlab-python-scilab/
はじめに
の、
MATLAB,Python,Scilab,Julia比較 第3章 その33【微分フィルタ⑨】
を書き直したもの。
Sobelフィルタの実験。
今回はPython(NumPy)で実施。
Sobelフィルタ【再掲】
まずは、Sobelフィルタと実験手順を再掲。
Sobelフィルタ
\(
K_{sbl}=
\begin{bmatrix}
1 \\
2 \\
1 \\
\end{bmatrix}
\begin{bmatrix}
-1 & 0 & 1
\end{bmatrix}=
\begin{bmatrix}
-1 & 0 & 1 \\
-2 & 0 & 2 \\
-1 & 0 & 1 \\
\end{bmatrix}
\)
実験手順
- 画像の読み込み
- ガウシアンフィルタ用のカーネル用意
- Sobelフィルタ用のカーネル用意
- SDTVグレースケール化実施
- ガウシアンフィルタ実施
- Sobelフィルタ実施
- 各Sobelフィルタの結果の合成
- 画像の書き出し
これをPython(NumPy)で実現する。
Pythonコード
Pythonコードはこうなる。
import numpy as np
import cv2
# 畳み込み演算
def convolution2d(img, kernel):
m, n = kernel.shape # カーネルサイズ取得
# カーネル中心からみた幅
dy = int((m-1)/2) # カーネル上下幅
dx = int((n-1)/2) # カーネル左右幅
h, w = img.shape # イメージサイズ
out = np.zeros((h, w)) # 出力用イメージ
# 畳み込み
for y in range(dy, h - dy):
for x in range(dx, w - dx):
out[y][x] = np.sum(img[y-dy:y+dy+1, x-dx:x+dx+1]*kernel)
return out
def sobel_test():
# 入力画像の読み込み
img = cv2.imread("dog.jpg")
b = img[:,:,0]
g = img[:,:,1]
r = img[:,:,2]
# ガウシアンフィルタ用のkernel
kernel_gauss = np.array([[1/16, 2/16, 1/16],
[2/16, 4/16, 2/16],
[1/16, 2/16, 1/16]])
# Sobelフィルタ用のKernel
kernel_sx = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
kernel_sy = kernel_sx.T
# SDTVグレースケール
gray_sdtv = np.array(0.2990 * r + 0.5870 * g + 0.1140 * b, dtype='uint8')
# ガウシアンフィルタ
img_g = convolution2d(gray_sdtv, kernel_gauss)
# Sobelフィルタ
img_sx = convolution2d(img_g, kernel_sx)
img_sy = convolution2d(img_g, kernel_sy)
cv2.imwrite("dog_sx.jpg",np.abs(img_sx))
cv2.imwrite("dog_sy.jpg",np.abs(img_sy))
# 合成
img_s = np.sqrt( img_sx**2 + img_sy**2 )
cv2.imwrite("dog_s.jpg",img_s)
return
sobel_test()
処理結果
処理結果は以下。
考察
結果はMATLABと一緒。
特筆するほどの話はほぼ無い。
油断するとnp.arrayがuint8じゃなくてdoubleになったりするから、
そこらへんが注意点だが、これはSobelフィルタに限った話ではない。
※ imwriteする段階で、uint8になっていないと期待しない動作になる。
まとめ
- Python(NumPy)でSobelフィルタを実施。
- MATLABと同じ結果が得られた。
- np.arrayがuint8になっている状態を維持する必要がある。
- imwrite時にuint8になっていないと期待した出力にならない。
MATLAB、Python、Scilab、Julia比較ページはこちら
コメント