前回は 画像から顔を検出しました。
今回は目を検出してみます。目の検出は 基本的には顔の検出と同じで 検出に用いる学習済みファイル(検出器と呼ぶらしい)が異なるだけです。ところでこの学習済みファイルは
OpenCV-2.3.1shareOpenCVhaarcascades に以下のファイルが格納されています。
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_lowerbody.xml
haarcascade_mcs_eyepair_big.xml
haarcascade_mcs_eyepair_small.xml
haarcascade_mcs_leftear.xml
haarcascade_mcs_lefteye.xml
haarcascade_mcs_mouth.xml
haarcascade_mcs_nose.xml
haarcascade_mcs_rightear.xml
haarcascade_mcs_righteye.xml
haarcascade_mcs_upperbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_upperbody.xml
名前からなんとなく使用目的が推測できます。また各XMLの中に簡単なコメントが書いてありますがあまり親切なコメントではありません。早速実験してみることにします。
今回使うデータは WEBから拾った キャンディーズのスッピン??と思わせるような画像です。スーちゃんは昨年お亡くなりになりました。今回このような形で 不謹慎にもテストデータに使わせていただくことをお詫びするとともに 改めてスーちゃんのご冥福をお祈りします。
横道にそれますが キャンディーズが解散コンサートを後楽園球場で行った日 昇太は春日通りの真砂坂上近くの事務所から 『ランチャーン』『スーチャーン』『ミキチャーン』との歓声を遠くに聞きながら COBOLと格闘していました。そんな思い出も。。。。ホント若い!!! 昇太もあのころは若かった(笑い)!!!!
目の検出 |
コーディング
前回の『顔を検出する』プログラムの検出した矩形を表示するLOOPで 求めた矩形を 目を検出する処理に渡すことにしました。というのは少なくとも目は顔の中にあるはず だからです。
検出した顔の矩形を表示するLOOP
for (int i=0; i < getlst.size(); i++){ Rect rct = getlst.get(i); Point pt1 = new Point(rct.x ,rct.y); Point pt2 = new Point(rct.x + rct.width , rct.y + rct.height); Core.rectangle(mat, pt1, pt2, new Scalar(255,255,255), 2); fncDetectEye(mat,gray,rct); // ここを追加 }
目を検出して表示する処理は受け取った矩形のsubmatを切り出して・・
private void fncDetectEye(Mat mat,Mat gray, Rect Rct){ String cascade_eye_path=Environment.getExternalStorageDirectory() +"/DCIM/100ANDRO/haarcascade_eye.xml"; CascadeClassifier cascade_eye = new CascadeClassifier(); cascade_eye.load(cascade_eye_path); //検索用submat切り出し Mat sub = new Mat(); gray.submat(Rct.y, Rct.y + Rct.height, Rct.x, Rct.x + Rct.width).copyTo(sub); //検索結果格納領域 List geteyelist = new ArrayList(); //検索処理 cascade_eye.detectMultiScale(sub, geteyelist, 1.1, 3, Objdetect.CASCADE_SCALE_IMAGE); //検索結果表示処理 for (int i=0; i < geteyelist.size(); i++){ Rect rct = geteyelist.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); } }
CascadeClassifier を作成する際に読み込む学習済みXMLをhaarcascade_eye.xmlにしたこと以外 基本的には顔の検出と同じです。(検出処理の引数は若干変えてます)
検出結果 きれいに検出できました。
他のXMLを使ってみる(pairは成功) |
OpenCV-2.3.1shareOpenCVhaarcascadesには ファイル名がeyeなんとかとなってるファイルが他にもいっぱいあります。
haarcascade_eye_tree_eyeglasses.xml
haarcascade_lefteye_2splits.xml
haarcascade_mcs_eyepair_big.xml
haarcascade_mcs_eyepair_small.xml
haarcascade_mcs_lefteye.xml
haarcascade_mcs_righteye.xml
haarcascade_righteye_2splits.xml
・haarcascade_eye_tree_eyeglasses.xmlはめがねをかけている人から検出する際に使うような感じがします。
・leftなんとか とか rightなんとかというファイルは それぞれ左目・右目を検出する際に使うのでは?? と思い試したところ今回のデータでは口の周り・鼻などそこいらじゅう検出してしまい却下・・
・pairなんとかというファイルは 両目を一括して検出するのでは?? と思い
cascade_eye.detectMultiScale(sub, geteyelist, 1.1, 0, Objdetect.CASCADE_FIND_BIGGEST_OBJECT);
で以下の検索結果が得られました。
口・鼻を検出する |
段々慣れてきたので 口・鼻の検出をして見ました。目の検出と同様に 顔の検出結果表示LOOPからそれぞれの検出処理をよぶことにしました。
検出に使うファイルおよび検出処理は以下の通りです。
使用ファイル
口の検出 haarcascade_mcs_mouth.xml
鼻の検出 haarcascade_mcs_nose.xml
検出処理 cascade.detectMultiScale(sub, getlist, 1.1, 0, Objdetect.CASCADE_FIND_BIGGEST_OBJECT);
検出した口は赤い円 鼻は黄色い矩形で示しました。
by Android2.2 with OpenCv 2.3.1 for Android |