8

私は、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);
}
4

3 に答える 3

4

とでcvtColorを使用してみましたか。したがって、フレームRGBAをRGBに変換してから、バックグラウンド減算を実行してみてください。このようなもの:CV_RGB2RGBACV_RGBA2RGB

protected void processFrame(VideoCapture capture) {
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    Mat rgb;
    Imgproc.cvtColor(mRgba, rgb, Imgproc.COLOR_RGBA2RGB);
    mBGSub.apply(rgb, mFGMask);
}

編集:ここBackgroundSubtractorMOGにあるOpenCVユニットテストをチェックしてください。ただし、テストはメインのテストケースにあります。fail("Not yet implemented");

それがテストが完了していないことを意味するのか、それとものサポートBackgroundSubtractorMOGが実装されていないのかはわかりません。この単体テストに含まれているコードを実行して、実際に機能するかどうかを確認してみてください。

また、C++サンプルのsegment_objects.cppが使用例として役立つ場合があります。

お役に立てば幸いです。:)

于 2012-02-12T05:48:37.457 に答える
2

どうもありがとうございました!そして、このページにアクセスする将来の視聴者のために、物事を機能させるためにこの知識を微調整する必要があるかもしれません。SDK v2.4.4では、これをonCameraFrameメソッドに適用しました。このメソッドはカメラから入力フレームを取り込むことを思い出してください。入力を使用して、Androidデバイスの画面に表示されるフレームを返します。次に例を示します。

//Assume appropriate imports    
private BackgroundSubtractorMOG sub = new BackgroundSubtractorMOG(3, 4, 0.8);
private Mat mGray = new Mat();
private Mat mRgb = new Mat();
private Mat mFGMask = new Mat();

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mGray = inputFrame.gray(); //I chose the gray frame because it should require less resources to process
    Imgproc.cvtColor(mGray, mRgb, Imgproc.COLOR_GRAY2RGB); //the apply function will throw the above error if you don't feed it an RGB image
    sub.apply(mRgb, mFGMask, learningRate); //apply() exports a gray image by definition

    return mFGMask;
}

apply()から出てくるグレー画像についての私のポイントを理解するために、RGBAバージョンを実行したい場合は、apply()の呼び出し後にcvtcolorを使用する必要があります。

private Mat mRgba = new Mat();

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    Imgproc.cvtColor(mRgba, mRgb, Imgproc.COLOR_RGBA2RGB); //the apply function will throw the above error if you don't feed it an RGB image
    sub.apply(mRgb, mFGMask, learningRate); //apply() exports a gray image by definition
    Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2RGBA);

    return mRgba;
}
于 2013-03-05T07:24:12.240 に答える
0

また、最新のopenCVでは、次のコマンドで初期化する必要があります。

private BackgroundSubtractorMOG2 Sub = Video.createBackgroundSubtractorMOG2();

于 2016-02-10T05:45:45.913 に答える