2012-02-12 55 views
8

私は、Android携帯をメインプロセッサとして使用し、カメラは動きを検出するためにロボットプロジェクトに取り組んでいます。私はAndroid binary package from OpenCVを得て、正しくインストールされています。私は、OpenCVネイティブカメラを使用して画像をキャプチャし、それらを画面に表示することができます。私はバックグラウンド減算クラスを使用して問題を抱えています。コンストラクタで新しいBackgroundSubtractorMOGオブジェクトを作成することはできますが、以下のコードを実行しようとすると、強制的に終了します。「ネイティブコードからBackgroundSubtractorMOGで1〜3チャネルの8ビット画像だけがサポートされています。私はHighgui.CV_CAP_ANDROID_COLOR_FRAME_RGBAをHighgui.CV_CAP_ANDROID_COLOR_FRAME_RGBに変更しようとしましたが、強制終了しませんが、黒い画面しか表示されません。画面が黒くなっているので、BMPがまだFRAME_RGBでヌルであることは確かです。ビットマップ(ビットマップの後に明瞭にするため、またトラブルシューティングのステップとして削除されたコードから削除)が表示されていません。OpenCV Android Background Subtraction

この関数のOpenCV C++コード(line 388 here)を見て、イメージタイプがCV_8UC1またはCV_8UC3でない場合はイメージタイプエラーが発生するため、Highguiの代わりにJava CvType.CV_8UC3を使用してみました。 capture_retrieve()のCV_CAP_ANDROID_COLOR_FRAME_RGBAが強制的に閉じられ、「出力フレームフォーマットはサポートされていません」というエラーが出ます。

私はちょうどタイプ変換の問題を抱えていると思いますが、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(); 
    } 
} 

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); 
} 

答えて

3

あなたはCV_RGB2RGBACV_RGBA2RGBcvtColorを使用しようとしています。ですから、フレームRGBAをRGBに変換してから、バックグラウンド減算をしてみてください。このような何か:

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); 
} 

EDITは:あなたはhere位置BackgroundSubtractorMOGのためのOpenCVのユニット・テストをチェックアウトすることがあります。ただし、テストはメインテストケースでfail("Not yet implemented");です。

これは、テストが完了していないか、またはBackgroundSubtractorMOGのサポートが実装されていないかどうかはわかりません。このユニットテストに含まれているコードを実行して、実際に動作するかどうかを調べることがあります。

また、C++のサンプルsegment_objects.cppも使用例として役立ちます。

希望に役立ちます! :)

+0

これは私を近づけます。 Javaラップされたバージョンの正確な構文は次のとおりです: 'Imgproc.cvtColor(mRgba、rgb、Imgproc.COLOR_RGBA2RGB);'最初の変換では2番目の変換は必要ありません(私は生の画像で何もしません減算の後に)。さて、黒い画面が表示されます(強制的に閉じることはありません)。ビットマップ形式をBitmap.Config.RGB_565に変更すると、FPSカウンタが戻ってくるので、実行中であることがわかりますが、それでもまだ黒い画面です。しかし、もう少し一緒になってくれてありがとう。 – RedPeasant

+0

@RedPeasant正しい構文の情報をありがとう。私はそれを含めるために私の答えを更新しました。カメラは動いていて、画面はまだ黒ですか? – mevatron

+0

@RedPeasant 'BackgroundSubtractorMOG'に関するより多くの情報を含めるために私の答えを更新しました。 – mevatron

1

ありがとう皆さん!このページに来る今後の視聴者にとっては、この知識を調整して機能させる必要があるかもしれません。 SDK v2.4.4では、onCameraFrameメソッドでこれを適用しました。カメラから入力フレームを取り込むことを思い出してください。入力を使用し、アンドロイドデバイスの画面に表示されるフレームを返します。ここでは例です:あなたはRGBA版をやってみたかった場合

//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; 
} 

適用から外れるグレー画像についての私のポイント間で取得するには()、あなたは(適用を呼び出した後cvtcolorを使用する必要があります):あなたがして初期化する必要があり、最新のOpenCVとも

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; 
} 
+0

BackgroundSubtractorMOGコンストラクタの値を選択する方法がわかりません。私は別のスレッドでそれらを見た。あなたのアプリケーションに合った値にしてください。 – austin

0

プライベートBackgroundSubtractorMOG2サブ= Video.createBackgroundSubtractorMOG2();