カメラ入力画像は、Camera.setPreviewCallbackWithBuffer(Camera.PreviewCallback)と Camera.addCallbackBuffer(byte[])でコールバックを設定して取得します。
CameraSourceでは createCamera()の最後の部分、そしてコールバック関数自体は CameraPreviewCallbackクラスの onPreviewFrame(byte[], Camera)です。
コールバック関数にデータが来る → 顔検出 の繰り返しとなります。
また、顔検出処理は時間がかかるので別スレッドで行います。
顔検出準備
取得した画像データから、Frameクラスを生成します。
Frame frame = new Frame.Builder().setImageData(data, width, height, ImageFormat.NV21).build();
YUV形式に対応していますのでカメラから取得したデータをそのまま使えます。
・画像の向き
顔検出APIは、検出する顔と画像の上下が合っていることが前提となっています。
カメラ画像は横向きなので、端末を縦に使う場合等は画像を回転する必要があります。
Frame frame = new Frame.Builder().setImageData(data, width, height, ImageFormat.NV21).setRotation(rotation).build();
setRotation(int)によって回転角を指定します。
引数は ROTATION_0 〜 ROTATION_270と、90°単位です。
CameraSource(というより
FaceTracker)では、screenOrientationを fullSensorにして getDefaultDisplay().getRotation()から計算しています(大雑把に言うと)。
さて前述の setTrackingEnabled(true)での注意点ですが、
「
おかしな(ヵ_ォ)カメラ」のようなリアルタイムで端末の向きを変えられるアプリの場合、setTrackingEnabled(true)としていると向きが変わったときにエラーが出て顔の検出ができなくなってしまいます。画像としては不連続になるからなんだとは思いますが。
そのため端末の向きが変わったときは FaceDetectorを一旦 release()して生成し直す必要があります。
顔検出
あとは FaceDetectorに Frameを放り込んで顔検出情報 Faceの配列を取得するだけです。
SparseArray <Face> faces = detector.detect(frame);
セコメントをする