2012年3月11日日曜日

画像の膨張・収縮処理を行う その1 - OpenCV for Android


今回も画像の膨張・収縮とは何ぞやから入りましょう。


主に2値化された画像に対して、対象の周辺に白い画素が1画素でもあれば白に置き換える処理を膨張、逆に周辺に黒い画素があれば黒に置き換える処理を収縮と言うそうです。
膨張と収縮を同じ回数実行することで、大きなパターンだけ残すような処理に良く利用します。


画像の膨張を行うには、Imgproc.dilate()メソッド、収縮にはImgproc.erode()メソッドを利用します。

Imgproc.dilate(Mat src, Mat dst, Mat kernel,
Point anchor, int iterations, int borderType, Scalar borderValue)

Imgproc.erode(Mat src, Mat dst, Mat kernel,
Point anchor, int iterations, int borderType, Scalar borderValue)


Mat src        処理したい元画像のMat
Mat dst        変換後Mat
Mat kernel      使用する構造要素を表すMat
Point anchor     要素内のアンカー位置
int iterations     実行回数
int borderType    ピクセル外挿手法
Scalar borderValue  定数境界モードで利用されるピクセル値


kernelについては、デフォルトが3×3で、1×1だと何もおこりません。
設定することで、膨張、収縮の度合いを縦横で差をつけることが出来ます。
独自の形状も使えるようです。
※Matのコンストラクタでサイズを指定するとうまくいかないようです。
 12/3/20修正。詳細はその3を参照。

anchorについては、デフォルトがkernelの中心を表す特別な値でPoint(-1、-1)です。
いくつか試してみましたが、結果に差は認められませんでした。

borderTypeとborderValueは画像を回転する その2 - OpenCV for Androidの第6引数以下と同じで、画像の外側をどう扱うかを指定します。

anchor以下は省略可能です。


それでは実際にやってみましょう。

元画像です。


すべてデフォルトで膨張してみます。
Imgproc.dilate(mat, mat, new Mat());


使用する構造要素を1×10に設定します。縦方向に膨張します。
getStructuringElement()メソッドについてはその3で説明します。
Imgproc.dilate(mat, mat,
  Imgproc.getStructuringElement(Imgproc.MORPH_RECT,
  new Size(1, 10)));



使用する構造要素を10×1に設定します。横方向に膨張します。
Imgproc.dilate(mat, mat,
  Imgproc.getStructuringElement(Imgproc.MORPH_RECT,
  new Size(10, 1)));



画像の外側を白として扱い、分かりやすいように縦方向のみ膨張します。
Imgproc.dilate(mat, mat,
  Imgproc.getStructuringElement(Imgproc.MORPH_RECT,
  new Size(1, 20)), new Point(-1, -1), 1,
  Imgproc.BORDER_CONSTANT, new Scalar(255, 255, 255));



デフォルトのままで実行回数を増やしてみます。
Imgproc.dilate(mat, mat, new Mat(),
  new Point(-1, -1), 3);




収縮もやってみます。
Imgproc.erode(mat, mat, new Mat(),
  new Point(-1, -1), 3);



ちなみにこれカラー画像やグレースケールに対して実行するとどうなるのでしょう?

グレースケール。



カラー。



水墨画や水彩画のようになりましたね。


0 コメント:

コメントを投稿