2013-10-18 2 views
3

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

답변

2

당신이 (initAsync) 언급 라인은 실제로 OpenCV의 관리자를로드하는 데 사용됩니다. 그것은 당신이하는 첫 번째 일이되어야합니다. 따라서 그것은 아마도 onStart()의 시작 부분에 있어야합니다.

+0

그래, 나는 그것을 시도 할 것이다. 나는 [이 기사] (http://answers.opencv.org/question/14717/using-default-baseloadercallback-in-an-android/)가 같은 것을 말하고 있음을 알았다. – Matthias

+0

작동하지 않았습니다. OpenCV로드는 그런 식으로 작동했지만 내부적으로 OpenCV는 카메라 서비스에 연결할 수 없다는 예외를 던졌습니다. 나는 dummy EGL SurfaceTexture를 만들고 그 텍스쳐를 미리보기로 카메라에 설정함으로써 서비스에서 기본 안드로이드 카메라 구현을 사용했다. 자세한 내용은 [이 기사] (http://stackoverflow.com/questions/2386025/android-camera-without-preview)를 참조하십시오. – Matthias

관련 문제