現在、アプリケーションは Snapdragon SDK を正常に実行しています。互換性のあるデバイスの数を増やすために、プロジェクトに Vision 8.3.0 の FaceDetector を実装しようとしています。特定の機能を提供するためにカスタム カメラ + サーフェスに依存しているため、CameraSource は使用できません。できるだけ多くのコードを再利用したいと考えており、Snapdragon SDK は現在の実装で驚くほどうまく機能しています。
ワークフローは次のとおりです。
1) カメラのプレビューを取得する
2) 入力バイト配列をビットマップに変換します (何らかの理由で、ByteBuffers を操作できませんでした。画像サイズ、回転、および NV21 画像フォーマットが提供され、検証されましたが、顔が見つかりませんでした)。Bitmap は、割り当てによる速度低下を避けるために、処理スレッド内で既に初期化されているグローバル変数です。
3) receiveFrame を介したフィード検出器
これまでの結果は十分ではありません。ランドマークと分類を無効にしていても、検出は遅すぎて (2 ~ 3 秒) 不正確です。
問題は、前者を使用せずに CameraSource + Detector のパフォーマンスを複製することは可能ですか? ライブ入力で動作させるために CameraSource を使用することは必須ですか?
前もって感謝します!
編集
以下の pm0733464 の推奨事項に従って、Bitmap の代わりに ByteBuffer を使用しようとしています。これは私が従う手順です:
// Initialize variables
// Mat is part of opencvSDK
Mat currentFrame = new Mat(cameraPreviewHeight + cameraPreviewHeight / 2, cameraPreviewWidth, CvType.CV_8UC1);
Mat yuvMat = new Mat(cameraPreviewHeight + cameraPreviewHeight / 2, cameraPreviewWidth, CvType.CV_8UC1);
// Load current frame
yuvMat.put(0, 0, data);
// Convert the frame to gray for better processing
Imgproc.cvtColor(yuvMat, currentFrame, Imgproc.COLOR_YUV420sp2RGB);
Imgproc.cvtColor(currentFrame, currentFrame, Imgproc.COLOR_BGR2GRAY);
ここから、バイト配列の作成:
// Initialize grayscale byte array
byte[] grayscaleBytes = new byte[data.length];
// Extract grayscale data
currentFrame.get(0, 0, grayscaleBytes);
// Allocate ByteBuffer
ByteBuffer buffer = ByteBuffer.allocateDirect(grayscaleBytes.length);
// Wrap grayscale byte array
buffer.wrap(grayscaleBytes);
// Create frame
// rotation is calculated before
Frame currentGoogleFrame = new Frame.Builder().setImageData(buffer, currentFrame.cols(), currentFrame.rows(), ImageFormat.NV21).setRotation(rotation).build();
この方法でフレームを構築すると、面が見つかりません。ただし、ビットマップを使用すると、期待どおりに機能します。
if(bitmap == null) {
// Bitmap allocation
bitmap = Bitmap.createBitmap(currentFrame.cols(), currentFrame.rows(), Bitmap.Config.ARGB_8888);
}
// Copy grayscale contents
org.opencv.android.Utils.matToBitmap(currentFrame, bitmap);
// Scale down to improve performance
Matrix scaleMatrix = new Matrix();
scaleMatrix.postScale(scaleFactor, scaleFactor);
// Recycle before creating scaleBitmap
if(scaledBitmap != null) {
scaledBitmap.recycle();
}
// Generate scaled bitmap
scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), rotationMatrix, true);
// Create frame
// The same rotation as before is still used
if(scaledBitmap != null) {
Frame currentGoogleFrame = new Frame.Builder().setBitmap(scaledBitmap).setRotation(rotation).build();
}