OpenCVの GaussianBlur()
で実際に適用されるカーネルの中身は、要素がすべて0で中心だけが1の画像に cv.GaussianBlur()
を適用することで調べられます。
5×5のカーネルのときは次のようになります(Python版)。
>>> import cv2
>>> import numpy as np
>>> img = np.zeros((5, 5))
>>> img[2, 2] = 1
>>> img
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
>>> filter = cv2.GaussianBlur(img, (5, 5), 0)
>>> filter
array([[0.015625, 0.03125 , 0.046875, 0.03125 , 0.015625],
[0.03125 , 0.0625 , 0.09375 , 0.0625 , 0.03125 ],
[0.046875, 0.09375 , 0.140625, 0.09375 , 0.046875],
[0.03125 , 0.0625 , 0.09375 , 0.0625 , 0.03125 ],
[0.015625, 0.03125 , 0.046875, 0.03125 , 0.015625]])
もとネタはstack overflow の「How do I get to show Gaussian Kernel for 2d? (opencv)」という記事です(Chris Luengoという方の2020年4月のポスト)。方法を探していたら行き当たったのですが、説明があまりにかっこよくて感激しました。曰く「これ(中心だけ1のカーネル)はディラックのデルタ関数と等価である」。気づかんかったぁ!
単にコピーするだけでは付加価値がないので、JavaScript/Node.js版も示します。
Module = {
onRuntimeInitialized() {
let img = new cv.Mat(5, 5, cv.CV_8UC1, new cv.Scalar(0));
img.data[5*2 + 2] = 1;
img.convertTo(img, cv.CV_32FC1);
console.log('img: ', img.data32F);
let kernel = new cv.Mat()
cv.GaussianBlur(img, kernel, new cv.Size(5, 5), 0);
console.log('kernel: ', kernel.data32F);
}
}
const cv = require('./opencv.js');
結果はもちろん上記と同じ。