Programming

UnityでOpenCV その3

Programming
スポンサーリンク

最近、ブログの更新がtwitter連携ばかりですいません((´・ω・`;))
今日は久しぶりに、UnityでOpenCVの続きを書こうと思います。
今回はいよいよ、画像処理のメインの一つ「輪郭抽出」をやっていきます。
【前回のおさらい】
この記事を参照。
前回は二値化処理がメインでした。
・二値化処理は、濃淡のある画像(グレー)を、一定の閾値で白黒(モノクロ)画像にする
・グレー画像のMatに、Imgproc.thresholdメソッドを施すだけ
・自動で閾値を判断させる(適応的閾値処理)には、Imgproc.adaptiveThresholdメソッドを使う

【輪郭抽出とは】
輪郭抽出とは、画像の特定の領域の境界線、つまり輪郭を求めるための処理です。
ただ、どこの領域を選ぶかが非常に重要で、適切に選べないと思ったように輪郭が抽出できない、あるいは処理が重いといった結果となります。
【抽出の前処理】
この輪郭抽出の領域をアルゴリズムに与えるための処理として、前回の二値化処理が出てきたわけです。
ただ、単純な二値化では細かいノイズや輪郭のギザギザ、余計な部分などが残ることも多く、輪郭が思うように抽出できないこともあります。
そこで適応的閾値処理でフィルタ(ガウシアンフィルタメディアンフィルタ)をかけて、平滑化(スムージング)を施すことで、細かい領域を省いて抽出したい部分を強調することができます。
フィルタをかけるだけでなく、二値化処理で現れた画素領域自体を膨張、あるいは収縮することで細かい部分を取り除く手法もよく使われます。膨張処理はImgproc.erode、収縮処理はImgproc.dilateメソッドを使います。
また、これらの処理を繰り返して抽出範囲を得るオープニング・クロージング処理もあり、これらはImgproc.morphologyExメソッドを使います。
【抽出処理】
前述の処理を施してようやく領域がわかったところで、いよいよ輪郭を求める処理に入ります。
OpenCVではImgproc.findContoursメソッドを使うだけで簡単に求められます。
輪郭は単にそれぞれの場所に点々と存在するだけでなく、輪郭の中にさらに輪郭が出てくることもあります(ちょうど等高線のようなイメージ)。そのため、輪郭抽出の方法もいくつかあり、外側だけを抜き取るか内側も含めるか、あるいは輪郭の各点(ピクセル)もそのまま記憶するかある程度近似するかをメソッド内で指定できます。
【輪郭線の近似】
輪郭線の近似は、主に直線近似凸包近似という手法があります。
前者は、ある距離以内の点を一直線にまとめて結ぶもので、グラフの近似曲線をつないでいくイメージに近いといえます。
後者は、輪郭をすべて含む最小の凸図形で囲む方式で、「輪ゴムで囲うようにぴったりと囲んだ線の図形」とたとえられます。
(もちろん、近似せずに各点からなる輪郭線をそのまま使うのもOK)
輪郭の各点を近似して取得するのはfindContoursメソッドで行いますが、直線近似はImgproc.approxPolyDP、凸包近似はImgproc.convexHullメソッドで求めます。
と、技術的な解説が長くなってしまったため、実装については次の記事で解説します。
【参考】
画像処理の流れについては、こちらの記事がわかりやすいと思います。
機械学習のためのOpenCV入門
適応的閾値処理のフィルタについては、こちらを参照。
ガウシアンフィルタメディアンフィルタ
平滑化処理の膨張・収縮などについてはこちらを参照。
膨張・収縮・オープニング・クロージング
ImgProc.findContoursの動作については以下を参照
opencv 2.2 documentation – OpenCV.jp
findContours関数の仮まとめ
画素領域の構造ツリーと処理に関しては、ラベリングを参照。
イメージングソリューション ラベリング

コメント

タイトルとURLをコピーしました