Android 기기가 부팅 될 때 시작되는 서비스를 사용하고 있습니다. 나는 눈에 보이는 활동이 필요 없기 때문입니다. 지금까지 잘 작동합니다. 하지만 지금은 (MyService.onStart에서) 카메라를 열고 기본적인 이미지 처리를하려고합니다. 기본 Android 카메라 클래스에는 동영상 미리보기 용 서페이스가 필요하다는 것을 알았습니다. 그래서 OpenCV에서 VideoCapture를 사용하고 싶습니다. 주요 활동을 사용 OpenCV의 예에서 사용 된 나는 다음 줄이 없기 때문에이 경우 내가 궁금하네요Android : 서비스에서 OpenCV VideoCapture 사용
No implementation found for native Lorg/opencv/highgui/VideoCapture;.n_VideoCapture:(I)J
:
는하지만이 오류가 발생합니다. 문제는 내 서비스에서이를 통합하고 VideoCapture 멤버를 초기화하는 방법입니다.
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5, this, mLoaderCallback);
여기까지 내 코드가 있습니다. OpenCV의 코드의 대부분을 OpenCV의 NativeCameraView에서 촬영되고 CameraBridgeViewBase는
package com.example.boot;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public final class MyService extends Service
{
private static final String TAG = "MyService";
private boolean mStopThread;
private Thread mThread;
private VideoCapture mCamera;
private int mFrameWidth;
private int mFrameHeight;
private int mCameraIndex = -1;
private Bitmap mCacheBitmap;
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
this.disconnectCamera();
Toast.makeText(this, "service stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
@Override
public void onStart(Intent intent, int startid)
{
Log.d(TAG, "service.onStart: begin");
try
{
if (!connectCamera(640, 480))
Log.e(TAG, "Could not connect camera");
else
Log.d(TAG, "Camera successfully connected");
}
catch(Exception e)
{
Log.e(TAG, "MyServer.connectCamera throws an exception: " + e.getMessage());
}
Toast.makeText(this, "service started", Toast.LENGTH_LONG).show();
Log.d(TAG, "service.onStart: end");
}
private boolean connectCamera(int width, int height) {
/* First step - initialize camera connection */
if (!initializeCamera(width, height))
return false;
/* now we can start update thread */
mThread = new Thread(new CameraWorker());
mThread.start();
return true;
}
private boolean initializeCamera(int width, int height) {
synchronized (this) {
if (mCameraIndex == -1)
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
else
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID + mCameraIndex);
if (mCamera == null)
return false;
if (mCamera.isOpened() == false)
return false;
//java.util.List<Size> sizes = mCamera.getSupportedPreviewSizes();
/* Select the size that fits surface considering maximum size allowed */
Size frameSize = new Size(width, height);
mFrameWidth = (int)frameSize.width;
mFrameHeight = (int)frameSize.height;
AllocateCache();
mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, frameSize.width);
mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, frameSize.height);
}
Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")");
return true;
}
protected void AllocateCache()
{
mCacheBitmap = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888);
}
private void releaseCamera() {
synchronized (this) {
if (mCamera != null) {
mCamera.release();
}
}
}
private void disconnectCamera() {
/* 1. We need to stop thread which updating the frames
* 2. Stop camera and release it
*/
try {
mStopThread = true;
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mThread = null;
mStopThread = false;
}
/* Now release camera */
releaseCamera();
}
protected void deliverAndDrawFrame(NativeCameraFrame frame)
{
Mat modified = frame.rgba();
boolean bmpValid = true;
if (modified != null) {
try {
Utils.matToBitmap(modified, mCacheBitmap);
} catch(Exception e) {
Log.e(TAG, "Mat type: " + modified);
Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmpValid = false;
}
}
}
private class NativeCameraFrame
{
public Mat rgba() {
mCapture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
return mRgba;
}
public Mat gray() {
mCapture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
return mGray;
}
public NativeCameraFrame(VideoCapture capture) {
mCapture = capture;
mGray = new Mat();
mRgba = new Mat();
}
private VideoCapture mCapture;
private Mat mRgba;
private Mat mGray;
};
private class CameraWorker implements Runnable
{
public void run()
{
do
{
if (!mCamera.grab()) {
Log.e(TAG, "Camera frame grab failed");
break;
}
deliverAndDrawFrame(new NativeCameraFrame(mCamera));
} while (!mStopThread);
}
}
}
그래, 나는 그것을 시도 할 것이다. 나는 [이 기사] (http://answers.opencv.org/question/14717/using-default-baseloadercallback-in-an-android/)가 같은 것을 말하고 있음을 알았다. – Matthias
작동하지 않았습니다. OpenCV로드는 그런 식으로 작동했지만 내부적으로 OpenCV는 카메라 서비스에 연결할 수 없다는 예외를 던졌습니다. 나는 dummy EGL SurfaceTexture를 만들고 그 텍스쳐를 미리보기로 카메라에 설정함으로써 서비스에서 기본 안드로이드 카메라 구현을 사용했다. 자세한 내용은 [이 기사] (http://stackoverflow.com/questions/2386025/android-camera-without-preview)를 참조하십시오. – Matthias