Android OpenCV 応用
OpenCVを用いて輪郭の取得を行いましたが今回はその応用です。輪郭の取得を行いその中で最も大きい輪郭だけを表示する方法
輪郭の取得はImgproc.findContoursを用いますがその前に入力画像をシングルチャンネルに変換します。今回は肌色の部分だけが残るように抽出します。
/*------------------------------------------------------------------------------------------------
@Override
public Mat onCameraFrame(Mat inputFrame) {
Mat image = new Mat();
image = inputFrame;
Imgproc.cvtColor(image , image , Imgproc.COLOR_RGB2HSV);//色空間をRGB→HSVに変換
Core.inRange(image , new Scalar(0, 60, 80), new Scalar(25, 255, 255), image );//肌色抽出
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = Mat.zeros(new Size(5,5), CvType.CV_8UC1);
Imgproc.findContours( image, contours, hierarchy,
Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_TC89_L1);
//途中
}
--------------------------------------------------------------------------------------------------*/
ここまでで肌色の部分の輪郭を取得することができます。
次にもっとも大きい輪郭=面積が一番大きいものなのでImgproc.contourAreaを用いて各輪郭の面積を比較します。
/*----------------------------------------------------------------------------------------------------
int i=0;
double maxarea = 0;
if(contours.size()>0){//サイズが0の場合エラーになるので
while(contours.size() != 1){//contoursが1つなるまで繰り返す
if(maxarea < Imgproc.contourArea(contours.get(i))){//maxareaより大きいか
maxarea = Imgproc.contourArea(contours.get(i));
contours.remove(0);
i=1;
}else{
contours.remove(i);
}
}
}
----------------------------------------------------------------------------------------------*/
まず輪郭の数が0の場合は無視するために
if(contours.size()>0){}
で0の場合は処理しないようにします。
次に輪郭の数が1つだけならばその輪郭が1番大きいので
while(contours.size() != 1){}
で輪郭が1つの場合ループを抜けるようにします。
ループの中は
contours.get(i)でi番目の輪郭の情報が取れるので
Imgproc.contourArea(contours.get(i))で輪郭の面積を出します。
※maxareaより大きい場合はその輪郭の面積をmaxareaに代入し、1番初めにある輪郭を消去します。
それ以外の場合はその輪郭を消去します。
※を輪郭が1つになるまで処理を繰り返すと残った輪郭が1番大きい輪郭となります。そして輪郭が1つだけなのでループを抜けすべての処理が終わります。
Excuse me, May i ask about Counting Object in Android Watershed openCV ?
返信削除