私は、Androidスマートフォンをメインプロセッサとして使用し、カメラを使用して動きを検出するロボット工学プロジェクトに取り組んでいます。OpenCVからAndroidバイナリパッケージを入手しました正しくインストールされました。OpenCVネイティブカメラを使用して画像をキャプチャし、画面に表示できます。ただし、バックグラウンド減算クラスの使用に問題があります。コンストラクターで新しいBackgroundSubtractorMOGオブジェクトを作成できますが、以下のコードを実行しようとすると、強制終了します。ネイティブコードから「BackgroundSubtractorMOGでサポートされているのは1チャネルと3チャネルの8ビット画像のみ」というエラーが表示されます。Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBAをHighgui.CV_CAP_ANDROID_COLOR_FRAME_RGBに変更してみましたが、強制終了しませんが、画面が真っ暗になります。画面が黒のままで、ビットマップの直後に描画していたfpsカウンター(わかりやすくするため、トラブルシューティングの手順として以下に投稿されたコードから削除)が表示されないため、FRAME_RGBではbmpがまだnullであると確信しています。
この関数のOpenCVC++コード(ここでは388行目)を調べましたが、画像タイプがCV_8UC1またはCV_8UC3でない場合は画像タイプエラーが発生するため、Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBAの代わりにjavaCvType.CV_8UC3を使用してみましたCapture.retrieve()ですが、強制的に閉じられ、「出力フレーム形式はサポートされていません」というエラーが発生しました。
型変換の問題が発生したと思いますが、OpenCVのAndroid固有の画像タイプが、文書化されている通常の画像タイプとどこに適合するのか、私にはわかりません。どんな助けでもいただければ幸いです。
変数:
private SurfaceHolder mHolder;
private VideoCapture mCamera;
private Mat mRgba;
private Mat mFGMask;
private BackgroundSubtractorMOG mBGSub;
私のSurfaceViewのrun()関数:
public void run() {
Bitmap bmp = null;
synchronized (this) {
if (mCamera == null)
break;
if (!mCamera.grab()) {
Log.e(TAG, "mCamera.grab() failed");
break;
}
processFrame(mCamera);
bmp = Bitmap.createBitmap(mFGMask.cols(), mFGMask.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mFGMask, bmp);
}
if (bmp != null) {
Canvas canvas = mHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas);
}
bmp.recycle();
}
}
run()で参照されるprocessFrame()関数:
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
mBGSub.apply(mRgba, mFGMask);
}
編集:
最終的に機能したソリューション:
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
//GREY_FRAME also works and exhibits better performance
//capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_GREY_FRAME);
mBGSub.apply(mRgba, mFGMask, 0.1);
Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
}