円を検出する

直線を検出するメソッドには HoughLinesHougLinesPがあります。円を検出するメソッドは HoughCirclesになります。
HoughLines と HougLinesP の入力が2値化した画像なのに対し HoughCircles の入力は グレースケール画像になり 2値化処理はHoughCirclesの中でCanny変換が内部処理として行われます。円の抽出ロジックは CodeZineの記事を参照してください。
 HoughCirclesの形式は以下のようになります。

static void HoughCircles(Mat image, Mat circles, int method, double dp, double minDist)
static void HoughCircles(Mat image, Mat circles, int method, double dp, double minDist,
  double param1)
static void HoughCircles(Mat image, Mat circles, int method, double dp, double minDist,
  double param1, double param2)
static void HoughCircles(Mat image, Mat circles, int method, double dp, double minDist,
  double param1, double param2, int minRadius)
static void HoughCircles(Mat image, Mat circles, int method, double dp, double minDist,
  double param1, double param2, int minRadius, int maxRadius)
Mat image : 8ビット,シングルチャンネル,グレースケールの入力画像。
Mat circles : 検出された円を出力するベクトル。
 各ベクトルは,(x,y,R)の3要素のベクトルになります。
 (x,yは円の中心 Rは円の半径) 
int method : 2値化手法 現在のところ, CV_HOUGH_GRADIENT メソッドのみが実装されています。 
これ以外を指定するとエラーになります。
double dp : 画像分解能に対する投票分解能の比率の逆数。
 例えば, dp=1 の場合は,投票空間は入力画像と同じ分解能をもち 処理は重くなります。
 また dp=2 の場合は,投票空間の幅と高さは半分になります。
double minDist : 検出される円の中心同士の最小距離。
 このパラメータが小さすぎると,正しい円の周辺に別の円が複数誤って検出されることになります。
 逆に大きすぎると,検出できない円がでてくる可能性があります。
double param1 : 2値化手法ごとに指定するパラメータの 1 番目。
 CV_HOUGH_GRADIENT の場合は, Canny() エッジ検出に渡される2つの閾値の内,大きい方の閾値を表します。(小さい閾値は,この値の半分になります)。
double param2 : 2値化手法ごとに指定するパラメータの 2 番目。
  CV_HOUGH_GRADIENT の場合は,円の中心を検出する際の投票数の閾値を表します。
 これが小さくなるほど,より多くの誤検出が起こる可能性があります。より多くの投票を獲得した円が,最初に出力されます。
int minRadius : 円の半径の最小値。
int maxRadius : 円の半径の最大値。

 実行結果 
Mat circles = new Mat();
Imgproc.cvtColor(image , gray, Imgproc.COLOR_RGB2GRAY); 
Imgproc.HoughCircles(gray, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 10, 160, 50, 10, 20); 
fncDrwCircles(circles,image);

見つけた円は 関数fncDrwCirclesで描画しています。

private void fncDrwCircles(Mat circles ,Mat img) {
  double[] data;
  double rho;
  Point pt = new Point();
  for (int i = 0; i < circles.cols(); i++){
    data = circles.get(0, i);
    pt.x = data[0];
    pt.y = data[1];
    rho = data[2];
    Core.circle(img, pt, (int)rho, new Scalar(255, 0, 0),2);
  }
}

誤検出・検出漏れもありますが おおむね 石を検出しています。

 by Android2.2 with OpenCv 2.3.1 for Android
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする