おなじみの平滑化です。
はい。すいません。読めすらしません。
「へいかつか」と読みますが、いわゆるぼかし処理です。
いくつか種類があるようで、利用するフィルタ毎にメソッドが用意されています。
ガウシアンフィルタを用いた平滑化を行うにはImgproc.GaussianBlur()メソッドを利用します。
Imgproc.GaussianBlur(Mat src, Mat dst, Size ksize,
double sigma1, double sigma2, int borderType)
Mat src 処理したい元画像のMat
Mat dst 変換後Mat
Size ksize ガウシアンカーネルサイズ
double sigma1 ガウシアンカーネルのx方向の標準偏差
double sigma2 ガウシアンカーネルのy方向の標準偏差
int borderType ピクセル外挿手法
ksizeについては、ksize.widthとksize.heightがそれぞれ正の奇数である必要があります。
サイズを大きくすると、それだけぼかしが強くなります。
ゼロを指定した場合は、sigma1、sigma2から計算されます。
sigma1、sigma2については、それぞれx方向(横方向)、y方向(縦方向)の標準偏差です。
ksizeの対応する方向軸がゼロの場合のみ計算に利用されます。
片方がゼロであれば、もう片方と等しくなるよう設定され、両方がゼロであればksizeから計算されます。
borderTypeについては、
画像を回転する その2 - OpenCV for Androidの第6引数と同じで、画像の外側をどう扱うかを指定します。
例によって省略可能です。
メディアンフィルタを用いた平滑化を行うにはImgproc.medianBlur()メソッドを利用します。
Imgproc.medianBlur(Mat src, Mat dst, int ksize)
Mat src 処理したい元画像のMat
Mat dst 変換後Mat
int ksize アパーチャサイズ
ksizeについては、1より大きな奇数を指定します。
ネットで調べるとksizeによって、処理出来る画像の画像のビット深度が違うと書いてありますが、特にエラーは出ませんでした。
バイラテラルフィルタを用いた平滑化を行うにはImgproc.bilateralFilter()メソッドを利用します。
基本的に処理が重たい割りに、大きな変化はありません。
Imgproc.bilateralFilter(Mat src, Mat dst, int d,
double sigmaColor, double sigmaSpace, int borderType)
Mat src 処理したい元画像のMat
Mat dst 変換後Mat
int d 各ピクセル近傍領域の直径
double sigmaColor 色空間におけるフィルタシグマ
double sigmaSpace 座標空間におけるフィルタシグマ
int borderType ピクセル外挿手法
srcについては、tyepがCV_8UC1かCV_8UC3である必要があります。
CvType.typeToString(mat.type())で確認し、必要に応じて変換して処理します。
dについては、この値が大きくなるとぼかしが強くなります。
ゼロ以下の場合は、sigmaSpaceから計算されます。
sigmaColorについては、この値が大きくなると、近くにある色的により遠くのピクセルが混ぜ合わせられます。
sigmaSpaceについては、この値が大きくなると、より遠くのピクセル同士が影響しあいます。
dがゼロ以下の場合のみ計算に利用されます。
borderTypeについては、同じく省略可能です。
それでは長くなりましたが、実際にやってみましょう。
元画像です。
ガウシアンフィルタです。
Imgproc.GaussianBlur(mat, dstMat, new Size(11, 11), 0, 0);
ksizeを変更してみます。
Imgproc.GaussianBlur(mat, dstMat, new Size(51, 3), 0, 0);
メディアンフィルタです。
Imgproc.medianBlur(mat, dstMat, 7);
ksizeを変更してみます。
Imgproc.medianBlur(mat, dstMat, 21);
バイラテラルフィルタです。
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR);
Imgproc.bilateralFilter(mat, dstMat, 10, 50, 0);
Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_BGR2RGBA);
dを変更してみます。
かなり重たいです。
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR);
Imgproc.bilateralFilter(mat, dstMat, 50, 50, 0);
Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_BGR2RGBA);
しかし、なぜGaussianBlur()だけ大文字から始まるんでしょう??
謎です。