我正在开发一种应用程序,它希望从相机中抓取一些帧并执行标记检测,其范围是计算标记与设备的相对位置。
为了执行此操作,我假设使用在后台运行的服务并使用新线程执行我需要的操作(抓取,检测,计算)。之后,我使用了BoundService属性来执行MainActivity和该服务之间的对话(遵循官方教程)。
现在,我正在尝试运行我所做的事情,但是我遇到了一些问题:在OpenCV(async w / manager)成功初始化之后,代码什么也没做。
这是我的服务:
public class BackgroundService extends Service {
//the external thread to perform
Thread processThread;
//binder to clients
private final IBinder mBinder = new LocalBinder();
//tags
String TAG = "processing Thread";
String TAG2 = "Service work";
String TAG3 ="RUN METHOD";
// parameters for Aruco detection
public CameraParameters mCamParam;
protected float markerSize = 0.195f;
protected MarkerDetector mDetector;
protected Vector<Marker> mDetectedMarkers;
//camera interaction object
private mobileCamera mCamera;
private Mat mFrame;
//Translation and Rotation matrixes vectors
public Mat Tvec;
public Mat Rvec;
@Override
public IBinder onBind(Intent _intent) {
// TODO Auto-generated method stub
return mBinder;
}
/**
* class used for the client to access
* @author andre_fromde
*
*/
public class LocalBinder extends Binder {
BackgroundService getService() {
//return this instance of background service so clients can call methods
return BackgroundService.this;
}
}
/*
* Simply transform a mat in a string object.
*/
String Mat2String (Mat _mat) {
return _mat.dump();
}
/**
* Runnable object that encapsulate the RUN operations.
*/
Runnable marker_recognition = new Runnable() {
//Does the marker detection process.
public void run() {
Log.i(TAG3, "called RUN method of the service.");
while (true) {
Log.i(TAG3, "Starting processing thread");
synchronized (this) {
//controls is a mCamera object is active
if (mCamera == null) {
Log.i(TAG3, "exiting, no camera available.");
break; //if not a mCamera, exit
}
//grab and retrieve the frame
if (!mCamera.readFrame(mFrame)) {
Log.e(TAG3, "mCamera.grab() failed");
break; //if not a frame exit
}
//detection method
Log.i(TAG3, "starting detection");
mDetector.detect(mFrame, mDetectedMarkers, mCamParam, markerSize, mFrame);
//get the marker in first position
Log.i(TAG3, "getting first marker");
Marker mMarker = mDetectedMarkers.get(0);
//gets the Tvec and Rvec data
Log.i(TAG3, "getting TVEC and RVEC current values.");
Tvec = mMarker.getTvec();
Log.i(TAG3, "TVEC VALUES are:"+Tvec.dump());
Rvec = mMarker.getRvec();
Log.i(TAG3, "RVEC VALUES are:"+Rvec.dump());
}
Log.i(TAG3, "Ending processing thread");
}
}
};
/**
* Called when the service is started.
* Initialize the parameters needed.
*/
@Override
public void onCreate() {
Log.i(TAG2, "called Service onCreate. Start Aruco initialization");
//Aruco parameters
mCamParam = new CameraParameters();
mCamParam.readFromXML(Environment.getExternalStorageDirectory().getAbsolutePath()+"/calibration/camera.xml");
mDetector = new MarkerDetector();
mDetectedMarkers = new Vector<Marker>();
//this initialize the camera
Log.i(TAG2, "Init camera with 800x480 resolution.");
mCamera.initializeCamera(800, 480);
//creates the new thread with the runnable passed
Log.i(TAG2, "Aruco done. Camera initialized. Init new Thread");
processThread = new Thread(marker_recognition);
//starts the thread just created
Log.i(TAG2, "Starts the thread");
processThread.start();
}
/**
* This method is called when the service is started in the main activity
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
return START_STICKY;
}
/**
* Release the camera when the service is destroyed
* Stops the processThread
*/
@Override
public void onDestroy() {
Log.i(TAG2, "called service OnDestroy. Interrupt processThread and release camera res.");
processThread.interrupt();
mCamera.releaseCamera();
Log.i(TAG2, "Successful release of Thread+camera");
}
}
这是MainActivity:
public class MainActivity extends Activity {
public String TAG = "Project Marker Aruco";
//create a service
BackgroundService mBkgdService;
boolean mIsBound = false; //control for the binding of the service
/**
* Dialogues with OpenCV manager for initialization of libraries
*/
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
/**
* Defines callbacks for service binding, passed to bindService()
*
*/
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBkgdService = ((BackgroundService.LocalBinder)service).getService();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBkgdService = null;
}
};
/**
* Establish the connection
*/
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(this,
BackgroundService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/**
* Stops the connection
*/
void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
//Activity Lifecycle
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
//keeper of the screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
Log.i(TAG, "Called initAsync!");
doBindService();
Log.i(TAG, "Service on background started");
}
@Override
public void onPause()
{
Log.i(TAG, "called onPause");
super.onPause();
}
@Override
public void onDestroy()
{
Log.i(TAG, "called onDestroy");
super.onDestroy();
//calls the method that stopped connection with the service
doUnbindService();
}
@Override
public void onResume()
{
Log.i(TAG, "called onResume");
super.onResume();
}
mobileCamera类使用VideoCapture类与OpenCV函数进行相机交互。
有关信息,这是最后一个日志(如果有用):
01-17 18:24:22.521: I/Project Marker Aruco(32256): called onCreate
01-17 18:24:23.652: D/dalvikvm(32256): threadid=1: still suspended after undo (sc=1 dc=1)
01-17 18:24:26.635: I/Project Marker Aruco(32256): Called initAsync!
01-17 18:24:27.596: I/Project Marker Aruco(32256): Service on background started
01-17 18:24:27.606: I/Project Marker Aruco(32256): called onResume
01-17 18:24:27.636: D/OpenCVManager/Helper(32256): Service connection created
01-17 18:24:27.646: D/OpenCVManager/Helper(32256): Trying to get library path
01-17 18:24:27.746: D/OpenCVManager/Helper(32256): Trying to get library list
01-17 18:24:27.806: D/OpenCVManager/Helper(32256): Library list: ""
01-17 18:24:27.806: D/OpenCVManager/Helper(32256): First attempt to load libs
01-17 18:24:27.806: D/OpenCVManager/Helper(32256): Trying to init OpenCV libs
01-17 18:24:27.806: D/OpenCVManager/Helper(32256): Trying to load library /data/data/org.opencv.engine/lib/libopencv_java.so
01-17 18:24:27.806: D/dalvikvm(32256): Trying to load lib /data/data/org.opencv.engine/lib/libopencv_java.so 0x423d84e8
01-17 18:24:28.146: D/dalvikvm(32256): Added shared lib /data/data/org.opencv.engine/lib/libopencv_java.so 0x423d84e8
01-17 18:24:28.146: D/OpenCVManager/Helper(32256): OpenCV libs init was ok!
01-17 18:24:28.146: D/OpenCVManager/Helper(32256): First attempt to load libs is OK
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): General configuration for OpenCV 2.4.8 =====================================
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Version control: 2.4.8
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Platform:
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Host: Linux 3.2.0-56-generic x86_64
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Target: Linux 1 armv7-a
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): CMake: 2.8.12
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): CMake generator: Ninja
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): CMake build tool: /usr/local/bin/ninja
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Configuration: Release
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): C/C++:
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): Built as dynamic libs?: NO
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): C++ Compiler: /opt/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ (ver 4.6)
01-17 18:24:28.176: I/OpenCVManager/Helper(32256): C++ flags (Release):
-----various parameters ---- (not reported)
01-17 18:24:28.176: D/OpenCVManager/Helper(32256): Init finished with status 0
01-17 18:24:28.176: D/OpenCVManager/Helper(32256): Unbind from service
01-17 18:24:28.176: D/OpenCVManager/Helper(32256): Calling using callback
01-17 18:24:28.176: I/Project Marker Aruco(32256): OpenCV loaded successfully
01-17 18:24:28.186: I/Choreographer(32256): Skipped 32 frames! The application may be doing too much work on its main thread.
01-17 18:24:28.256: D/libEGL(32256): loaded /system/lib/egl/libEGL_mali.so
01-17 18:24:28.276: D/libEGL(32256): loaded /system/lib/egl/libGLESv1_CM_mali.so
01-17 18:24:28.276: D/libEGL(32256): loaded /system/lib/egl/libGLESv2_mali.so
01-17 18:24:28.296: D/OpenGLRenderer(32256): Enabling debug mode 0
01-17 18:24:36.885: I/Project Marker Aruco(32256): called onPause
01-17 18:24:37.525: I/Project Marker Aruco(32256): called onDestroy
我忘记了什么吗?
提前感谢任何提示。
此致
安德烈
ps:如果需要其他信息,请询问。