使用OpenFrameworks,OpenCV和Box2D,我能够以良好的帧速率实现它.使用
Android似乎是一项更复杂的任务(部分原因是我是JAVA新手).
这就是我的开始:
>使用“OpenCV示例 – 图像处理”并删除除“canny”效果之外的所有内容,这会产生一个漂亮的黑色&白色图像,非常适合找到轮廓.
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mRgba = inputFrame.rgba(); Imgproc.Canny(mRgbaInnerWindow,mIntermediateMat,50,100); Imgproc.cvtColor(mIntermediateMat,mRgbaInnerWindow,Imgproc.COLOR_GRAY2BGRA,4); return mRgba; }
>从“OpenCV Sample – color-blob-detection”中我抓住了在Mat中找到轮廓的逻辑:
// These two lines are actually in the function onCameraViewStarted mHierarchy = new Mat(); CONTOUR_COLOR = new Scalar(255,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,-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,100); //Imgproc.cvtColor(mIntermediateMat,4); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours(mRgbaInnerWindow,Imgproc.CHAIN_APPROX_SIMPLE); //Imgproc.drawContours(mIntermediateMat,CONTOUR_COLOR); return mRgba; }
>现在,这就是我被困的地方.我不断得到例外,我认为我没有使用正确的尺寸或将Mat转换为正确的颜色空间.这篇文章有一些见解,但我不知道它是否正确:OpenCV on Android findContours throws Exception
解决方法
嗨我也是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,CvType.CV_8UC4); mGray = new Mat(height,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,80,100); Imgproc.findContours(mIntermediateMat,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,i,color,2,8,new Point() ); }*/ hierarchy.release(); Imgproc.drawContours(mRgba,new Scalar(Math.random()*255,Math.random()*255));//,new Point()); // Imgproc.cvtColor(mIntermediateMat,mRgba,Imgproc.COLOR_GRAY2RGBA,4); return mRgba; } }
我知道这可能不是实现这一目标的最佳方式,但我们都在这里学习新方法:)