如何从Android相机中找到帧的轮廓并将其转换为box2d实体?
使用OpenFrameworks,OpenCV和Box2DI能够以良好的帧速率实现它。使用Android似乎是一项复杂得多的任务(部分原因是我是JAVA新手) 我是这样开始的:如何从Android相机中找到帧的轮廓并将其转换为box2d实体?,android,opencv,computer-vision,jbox2d,Android,Opencv,Computer Vision,Jbox2d,使用OpenFrameworks,OpenCV和Box2DI能够以良好的帧速率实现它。使用Android似乎是一项复杂得多的任务(部分原因是我是JAVA新手) 我是这样开始的: 使用“OpenCV示例-图像操作”,删除除“canny”效果之外的所有内容,该效果可生成一个很好的黑白图像,非常适合查找轮廓 public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mRgba = inputFrame.rgba(); Imgpro
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
{
mRgba = inputFrame.rgba();
Imgproc.Canny(mRgbaInnerWindow, mIntermediateMat, 50, 100);
Imgproc.cvtColor(mIntermediateMat, mRgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
return mRgba;
}
// 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);
//这两行实际上在onCameraViewStarted函数中
mHierarchy=新材料();
轮廓颜色=新标量(255,0,0255);
//这些行在CameraFrame上起作用
列表等高线=新的ArrayList();
Imgproc.findContours(内部窗口、等高线、层次结构、Imgproc.RETR_外部、,
Imgproc.链(近似简单);
Imgproc.绘制等高线(mIntermediateMat,等高线,-1,等高线颜色);
因此,我当前的函数看起来是这样的,但它不起作用:
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;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
{
mRgba=inputFrame.rgba();
如果((mRgbaInnerWindow==null)| |(mGrayInnerWindow==null)| |(mRgba.cols()!=mSizeRgba.width)|(mRgba.height()!=mSizeRgba.height))
CreateAxiliaryMats();
Imgproc.Canny(MrgbannerWindow,mIntermediateMat,50100);
//Imgproc.cvtColor(mIntermediateMat,mrgbainerwindow,Imgproc.COLOR_gray,4);
列表等高线=新的ArrayList();
Imgproc.findContours(mRgbaInnerWindow、等高线、mHierarchy、Imgproc.RETR\u EXTERNAL、Imgproc.CHAIN\u APPROX\u SIMPLE);
//Imgproc.绘制等高线(mIntermediateMat,等高线,-1,等高线颜色);
返回mRgba;
}
嗨,我也是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;
}
}
导入android.app.Activity;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.SurfaceView;
导入org.opencv.android.*;
导入org.opencv.core.*;
导入org.opencv.imgproc.imgproc;
导入java.util.ArrayList;
导入java.util.List;
公共类MainActivity扩展活动实现CvCameraViewListener2{
私有静态最终字符串标记=MainActivity.class.getCanonicalName();
私人摄像机BridgeViewBase mOpenCvCameraView;
私人Mat mRgba;
私人医疗设备;
私人马拉松;
垫层次;
列出等高线;
专用BaseLoaderCallback mlLoaderCallback=新BaseLoaderCallback(此){
@凌驾
已连接管理器上的公共无效(int状态){
开关(状态){
案例加载程序CallbackInterface.SUCCESS:
{
Log.i(标记“OpenCV已成功加载”);
mOpenCvCameraView.enableView();
}中断;
违约:
{
超级管理器已连接(状态);
}中断;
}
}
};
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mOpenCvCameraView=(CameraBridgeViewBase)findViewById(R.id.java\u surface\u view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(本);
}
@凌驾
恢复时公开作废(){
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,
mLoaderCallback);
}
@凌驾
公共无效暂停(){
super.onPause();
if(mOpenCvCameraView!=null)
mOpenCvCameraView.disableView();
}
@凌驾
开始时的公共空隙(整数宽度、整数高度){
mRgba=新垫(高度、宽度、CvType.CV_8UC4);
mIntermediateMat=新垫(高度、宽度、CvType.CV_8UC4);
mGray=新垫(高度、宽度、CvType.CV_8UC1);
层次结构=新的Mat();
}
@凌驾
CAMERAVIEWSTOPPED()上的公共空白{
mRgba.release();
mGray.release();
mIntermediateMat.release();
hierarchy.release();
}
@凌驾
CameraFrame上的公用Mat(CvCameraViewFrame输入框){
mRgba=inputFrame.gray();
等高线=新的ArrayList();
层次结构=新的Mat();
Imgproc.Canny(mRgba,mIntermediateMat,80100);
Imgproc.findContours(mIntermediateMat、等高线、层次、Imgproc.RETR_树、Imgproc.CHAIN_近似、简单、新点(0,0));
/*材料图纸=材料零点(最小中间材料尺寸(),CvType.CV_8UC3);
对于(int i=0;i
我知道这可能不是实现这一目标的最佳方式,但我们都在这里学习新的方法:)简短回答:您必须使用
Canny
的结果作为findContetors
的输入(第一个参数),即
Imgproc.findContours(mIntermediateMat, ...);
您使用的是什么box2d实现?它只是裸体的jbox2d吗?或者您正在使用类似于ANDEngine的东西?我一直在研究ANDEngine,但我还不知道如何使用ANDEngine的SimpleGameActivity实现CVCamera类。这会导致Canny检测不断闪烁是的,有人有更好的示例来避免闪烁?可能是因为它是实时的。