¿Cómo encontrar los contornos de un marco de una cámara Android y convertirlos en cuerpos box2d?

Utilizando OpenFrameworks, OpenCV y Box2D pude lograrlo con una buena velocidad de fotogramas. El uso de Android parece una tarea mucho más complicada (en parte porque soy un novato JAVA).

Así es como empecé:

  1. Utilice "OpenCV Sample – manipulaciones de imagen" y elimine todo excepto el efecto "canny", que produce una bonita imagen en blanco y negro que es perfecta para encontrar los contornos.

    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. Desde el "OpenCV Sample – color-blob-detection" agarré la lógica para encontrar los contornos en un 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); 

    Por lo tanto, mi función actual se parece a esto y no funciona:

     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. Ahora, aquí es donde estoy atrapado. Sigo recibiendo excepciones y creo que no estoy usando las dimensiones correctas o transformar el Mat en el espacio de color adecuado. Este post tiene alguna idea pero no sé si es correcto: OpenCV en Android findContours lanza Exception

Hola soy también un novato en openCV sin embargo este código podría ayudar,

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

Sé que esto puede no ser la mejor manera de lograr esto, pero estamos todos aquí para aprender nuevas maneras 🙂

Respuesta corta: findContours utilizar el resultado de Canny como entrada (1er argumento) para findContours , es decir

 Imgproc.findContours(mIntermediateMat, ...); 
  • Representación del modelo 3D de realidad aumentada
  • Opencv Android: java.lang.UnsatisfiedLinkError: dlopen falló: no se pudo cargar la librería "libopencv_java.so"
  • Android.mk y Application.mk para crear OpenCV 3.2
  • Android4OpenCV: configuración de la resolución al inicio
  • Android OpenCV Encuentra la plaza o rectángulo más grande
  • Abrir muestra de muestras de CV para OpenCV Manager descargar
  • OpenCV para Android: ejemplo simple para convertir la imagen a escala de grises
  • Gradle android build para diferentes arquitecturas de procesador
  • OpenCV: detección de puntos / discos circulares de dominó
  • cverror android assertion failed (scn == 3) Android
  • Android Studio 1.5 Opencv 3.0.0 calibración de la cámara de muestra se estrelló
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.