2013-04-19 23 views
7

Korzystając z OpenFrameworks, OpenCV i Box2D udało mi się to osiągnąć z dobrym współczynnikiem klatek na sekundę. Korzystanie z Androida wydaje się o wiele bardziej skomplikowanym zadaniem (częściowo dlatego, że jestem nowicjuszem JAVA).Jak znaleźć kontury klatki z aparatu z Androidem i przekonwertować je na ciała box2d?

ten sposób zacząłem:

  1. Użyj „OpenCV próbki - manipulacje obrazem” i usunąć wszystko z wyjątkiem „sprytny” efekt, który wytwarza piękny czarny & biały obraz, który jest idealnym miejscem, aby znaleźć kontury.

    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. Z „OpenCV próbki - kolor kropelka wykrywanie” Złapałem logikę znaleźć kontury w 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); 
    

    Tak, moja obecna funkcja wygląda tak, a nie robi „t praca:

    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. teraz to gdzie jestem stucked. Ciągle dostaję wyjątki i myślę, że nie używam właściwych wymiarów ani nie przekształcam Maty w odpowiednią przestrzeń barw. Ten post ma jakiś wgląd, ale nie wiem, czy to jest poprawne: OpenCV on Android findContours throws Exception

+0

Jakiej implementacji box2d używasz? Czy to tylko nagi jbox2d? A może używasz czegoś takiego jak ANDEngine? –

+0

Patrzyłem na AndEngine, ale jeszcze nie wiem jak wdrożyć klasę CVCamera z SimpleGameActivity of AndEngine. –

Odpowiedz

12

Cześć Jestem również początkującym w OpenCV jednak ten kod może pomóc,

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

} 

wiem, że to nie może być najlepszym sposobem na osiągnięcie tego celu, ale wszyscy jesteśmy tutaj, aby nauczyć się nowych sposobów :)

0

Krótka odpowiedź: trzeba korzystać z wynikiem Canny jako argumentu wejściowego (1) dla findContours, tj

Imgproc.findContours(mIntermediateMat, ...);