複数の矩形をグループ化する

オブジェクトの検出を行うと、オブジェクトとおぼしき周辺に多くの検出矩形が探し出されます。もちろんその中にはガセもあります。
実際 前回取り上げた 若かったキャンディーズのスッピン(?)画像から口を検出した際 処理モードに  CASCADE_SCALE_IMAGEを指定して検出処理を
cascade_mouth.detectMultiScale(sub, geteyelist, 1.1, 0, Objdetect.CASCADE_SCALE_IMAGE);
とすると 下のようにたくさん口が検出されてしまいました。そこで前回は 処理モードに CASCADE_FIND_BIGGEST_OBJECTを指定して最大の検出矩形だけを取り出しています。
ObjdetectクラスのgroupRectanglesメソッドを用いると、このように検出された複数の検出矩形をグルーピングすることができます。

static void groupRectangles(java.util.List rectList, int groupThreshold)
static void groupRectangles(java.util.List rectList, int groupThreshold, double eps)
static void groupRectangles(java.util.List rectList, int groupThreshold, double eps,java.util.List weights, java.util.List levelWeights)
static void groupRectangles(java.util.List rectList,java.util.List weights, int groupThreshold)
static void groupRectangles(java.util.List rectList,java.util.List weights, int groupThreshold, double eps)

java.util.List rectList : 矩形の入出力ベクトル。
  検出処理で検出した矩形のListを与え実行すると、グループ化された矩形が返ります。
int groupThreshold : 矩形グループにおいて最低限保持すべき矩形の数 – 1 の値。
  指定した数-1個に満たない矩形グループは却下されます。
double eps : グループ化するにあたって用いる 類似性。
  0にするとグループ化はしません。実験結果では この値を小さくすると 口でないところ例えばスーちゃんの目も口として残りました。
引数には weightsとかlevelWeightsといった引数も取れますが JavaDocにもなんの説明もないので 今回は次の形式で実験しました。
static void groupRectangles(java.util.List rectList, int groupThreshold, double eps)

 グループ化前の状態 

前回の口の検出処理のフラグをCASCADE_SCALE_IMAGEに変えると

private void fncDetectMouth(Mat mat,Mat gray, Rect Rct){String cascade_mouth_path=Environment.getExternalStorageDirectory()
    +"/DCIM/100ANDRO/haarcascade_mcs_mouth.xml";
  CascadeClassifier cascade_mouth = new CascadeClassifier();
  cascade_mouth.load(cascade_mouth_path);
  //検索用submat切り出し
  Mat sub = new Mat();
  gray.submat(Rct.y, Rct.y + Rct.height, Rct.x, Rct.x + Rct.width).copyTo(sub);
  //検索結果格納領域
  List getmouthlist = new ArrayList();
  //検索処理
 cascade_mouth.detectMultiScale(sub, getmouthlist, 1.1, 3, Objdetect.CASCADE_SCALE_IMAGE);
  //検索結果表示処理
  for (int i=0; i < getmouthlist.size(); i++){
    Rect rct = getmouthlist.get(i);
    Point center = new Point(Rct.x + rct.x + rct.width / 2 ,Rct.y + rct.y + rct.height / 2);
    int radius = rct.width / 2;
    Core.circle(mat, center, radius, new Scalar(0,255,255), 2);
  }
}

うーーーー そこいら中口だらけ(笑い)

 グループ化すると 

検索処理後 グループ化を入れて

//検索処理
cascade_mouth.detectMultiScale(sub, getmouthlist, 1.1, 3, Objdetect.CASCADE_SCALE_IMAGE);
Objdetect.groupRectangles(getmouthlist, 5, 1.0);

とすると

すっきりすっきり

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

シェアする

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

フォローする