7

OpenFrameworks、OpenCV、および Box2D を使用して、良好なフレームレートで達成できました。Android を使用することは、はるかに複雑な作業のように思えます (私が Java の初心者であることも一因です)。

これが私が始めた方法です:

  1. 「OpenCV サンプル - 画像操作」を使用し、輪郭を見つけるのに最適な素敵な白黒画像を生成する「キャニー」効果以外のすべてを削除します。

    public Mat onCameraFrame(CvCameraViewFrame inputFrame)
    {
        mRgba = inputFrame.rgba();
        Imgproc.Canny(mRgbaInnerWindow, mIntermediateMat, 50, 100);
        Imgproc.cvtColor(mIntermediateMat, mRgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
    
        return mRgba;
    }
    
  2. 「OpenCV Sample - color-blob-detection」から、Mat の輪郭を見つけるロジックを取得しました。

    // These two lines are actually in the function onCameraViewStarted
    mHierarchy = new Mat();
    CONTOUR_COLOR = new Scalar(255,0,0,255);
    
    // These lines are in function onCameraFrame
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();        
    Imgproc.findContours(mRgbaInnerWindow, contours, mHierarchy, Imgproc.RETR_EXTERNAL,     
    Imgproc.CHAIN_APPROX_SIMPLE);
    Imgproc.drawContours(mIntermediateMat, contours, -1, CONTOUR_COLOR);
    

    したがって、私の現在の関数は次のようになり、機能しません。

    public Mat onCameraFrame(CvCameraViewFrame inputFrame)
    {
        mRgba = inputFrame.rgba();
    
        if ((mRgbaInnerWindow == null) || (mGrayInnerWindow == null) || (mRgba.cols() != mSizeRgba.width) || (mRgba.height() != mSizeRgba.height))
            CreateAuxiliaryMats();
    
        Imgproc.Canny(mRgbaInnerWindow, mIntermediateMat, 50, 100);
        //Imgproc.cvtColor(mIntermediateMat, mRgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
    
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    
        Imgproc.findContours(mRgbaInnerWindow, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
        //Imgproc.drawContours(mIntermediateMat, contours, -1, CONTOUR_COLOR);
    
        return mRgba;
    }
    
  3. 今、これは私が立ち往生しているところです。例外が発生し続け、正しい寸法を使用していないか、マットを正しい色空間に変換していないと思います。この投稿にはいくつかの洞察がありますが、それが正しいかどうかはわかりません: OpenCV on Android findContours throws Exception

4

2 に答える 2

14

こんにちは私はopenCVの初心者でもありますが、このコードが役立つかもしれません.

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import org.opencv.android.*;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;


import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity implements CvCameraViewListener2{

private static final String TAG = MainActivity.class.getCanonicalName();

private CameraBridgeViewBase mOpenCvCameraView;

private Mat                    mRgba;
private Mat                    mIntermediateMat;
private Mat                    mGray;
Mat hierarchy;


List<MatOfPoint> contours;

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view);
    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);

    mOpenCvCameraView.setCvCameraViewListener(this);

}

@Override
public void onResume() {
    super.onResume();
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this,
            mLoaderCallback);
}

@Override
public void onPause() {
    super.onPause();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}



@Override
public void onCameraViewStarted(int width, int height) {
    mRgba = new Mat(height, width, CvType.CV_8UC4);
    mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
    mGray = new Mat(height, width, CvType.CV_8UC1);
    hierarchy = new Mat();
}

@Override
public void onCameraViewStopped() {
    mRgba.release();
    mGray.release();
    mIntermediateMat.release();
    hierarchy.release();
}

@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
     mRgba = inputFrame.gray();
        contours = new ArrayList<MatOfPoint>();
        hierarchy = new Mat();

     Imgproc.Canny(mRgba, mIntermediateMat, 80, 100);
     Imgproc.findContours(mIntermediateMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
    /* Mat drawing = Mat.zeros( mIntermediateMat.size(), CvType.CV_8UC3 );
     for( int i = 0; i< contours.size(); i++ )
     {
    Scalar color =new Scalar(Math.random()*255, Math.random()*255, Math.random()*255);
     Imgproc.drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, new Point() );
     }*/
     hierarchy.release();
     Imgproc.drawContours(mRgba, contours, -1, new Scalar(Math.random()*255, Math.random()*255, Math.random()*255));//, 2, 8, hierarchy, 0, new Point());
    // Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
    return mRgba;
}

}

これがこれを達成するための最良の方法ではないことはわかっていますが、私たちは皆、新しい方法を学ぶためにここにいます :)

于 2013-04-25T10:56:14.560 に答える
0

短い答え: の結果を のCanny入力 (第 1 引数) としてfindContours使用する必要があります。

Imgproc.findContours(mIntermediateMat, ...);
于 2017-07-25T20:46:25.480 に答える