OpenCL を使って ガウスぼかしをする(その1)
の続きです。
概要
ガウスぼかしは、重みづけ平滑化の1つである。
前回は、重みの値をプログラムファイルにハードコーディングした。
今回は、重みの値を計算によって求め、デバイス側プログラムに引数として渡す。
ガウスカーネルを計算する
2次元のガウス関数は、下記の関数で表現される。
この関数を単にガウシアン(Gaussian) とも呼ぶ。
G\left( x, y \right) = \dfrac {1}{ 2 \pi \sigma} \mathrm{e}^{ - \dfrac {x^{2} + y^{2}}{ 2 \sigma^{2} } }
図は下記より引用。
ネット検索したら、下記の記事を見つけた。
ガウスカーネルの2つのパラメータ大きさ(Kernel Size)と標準偏差(sigma) から、ガウスカーネルを計算するもの。
パラメータを変えると、ぼかしの効果がどう変わるのかは、多くの人の関心ごとのようだ。
C ++でのプログラム例も見つかった。
stackoverflow : Implementing Gaussian Blur - How to calculate convolution matrix (kernel)
これを参考に前回のコードを修正する。
コマンドラインから大きさと標準偏差を与えて、ガウスカーネルを計算する。
Usage: GaussianFilter
計算したガウスカーネルの値をデバイス側プログラムに引数として渡す。
memObjects[2] = createWeightBuffer(context, kernel2d, radius);
clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObjects[2]);
__kernel void gaussian_filter(
__read_only image2d_t srcImg,
__write_only image2d_t dstImg,
__constant float * weights,
sampler_t sampler,
int width,
int height,
int radius)
サンプルコードを Github に公開した。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/OpenCL-GaussianFilter
ガウスカーネルのパラメータとぼかしの効果
どのくらいのパラメータからぼかしの効果が現れるか試した。
サンプル画像は OpenCL のロゴとした。
大きさ 11x11 標準偏差 3.0 となった。
標準偏差が大きくなると、相対的に中心の重みが小さくなり、周辺の重みが大きくなる。
準偏差はばらつきの度合いを示す指標なので、当然の結果ですが。
図示することで、理解しやすくなる。
おまけ OpenCV を使ってガウスぼかしをする
OpenCVの GaussianBlur API を使う例を紹介する。
Mat img = imread(input);
GaussianBlur(img, dst, Size(ksize, ksize), sigma, sigma);
imwrite(output, dst);
サンプルコードはこちら。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/OpenCV-GaussianBlur