バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia3-backnumber/
はじめに
畳み込み演算のガウシアンフィルタの話。
今回はJuliaで実施してみる。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
使用する畳み込みカーネルと画像

まずは畳み込みカーネルと画像の再掲
畳み込みカーネル
\(
\displaystyle K_{3\times3}=\frac{1}{16}
\begin{bmatrix}
1 & 2 & 1 \\
2 & 4 & 2 \\
1 & 2 & 1 \\
\end{bmatrix}
\)
画像


これをJuliaで実現する。
Juliaコード

Juliaコードは以下になる。
using Images
# 畳み込み演算
function convolution2d(img, kernel)
(n, m) = size(kernel); # カーネルサイズ取得
# カーネル中心からみた幅
dy = Int64((n-1)/2); # カーネル上下幅
dx = Int64((m-1)/2); # カーネル左右幅
(h, w) = size(img); # イメージサイズ
out = zeros(h, w); # 出力用イメージ
# 畳み込み
for y = dy+1:(h - dy)
for x = dx+1:(w-dx)
out[y, x] = sum( img[y-dy:y+dy, x-dx:x+dx].*kernel );
end
end
return out;
end
function gaussian_test()
img = channelview(load("dog.jpg"));
(c, h, w) = size(img);
# ガウシアンフィルタ用のkernel
kernel_gauss = [ 1/16 2/16 1/16;
2/16 4/16 2/16;
1/16 2/16 1/16];
img_gauss = zeros( c, h, w );
# ガウシアンフィルタ
img_gauss[1,:,:] = convolution2d(img[1,:,:], kernel_gauss);
img_gauss[2,:,:] = convolution2d(img[2,:,:], kernel_gauss);
img_gauss[3,:,:] = convolution2d(img[3,:,:], kernel_gauss);
img_gauss = colorview(RGB, img_gauss);
save("dog_gaussian_j.jpg",img_gauss);
return;
end
gaussian_test();
処理結果

そして処理結果。

考察

これもMATLABに似た感じだねー。
まぁ画像の読み込み、書き込みでchannelview、colorviewを経由する必要はあるけど。

sumは、NumPy、Scilabと同じで、行列全体の総和が得られるのか。

そうだね。
dimsオプションを使うと、行、列の単位での総和が取れる。

細かく似てたり似てなかったりで大変だな・・・。

あと、Juliaは画像の構造が、
ch、高さ、幅
で埋まってる点に注意だな。
convolution2dの画像データの渡し方が変わってくる。

あ、ホントだ。
他のツール、言語だと、
img(:,:,1)
なところが
img[1,:,:]
になってるね。

まぁ、ここらへんを意識できていれば、処理の流れとしては全く一緒にできるってことだな。
まとめ

まとめだよ。
- Juliaでガウシアンフィルタを実施。
- 畳み込み演算は関数化。
- Juliaのsumは行列の総和。
- 行、列の総和の場合はdimsオプションを使用。
- RGB 3chに対して同じ処理を実施。
- データ構造が大きく異なるので注意。
バックナンバーはこちら。
コメント