2013-11-28 5 views
7

내 안드로이드 앱은 JavaCameraView의 액티비티로 안드로이드 용 opencv로 이미지 처리를 수행합니다. 잘 작동합니다. 이제 사용자를위한 미리보기없이 백그라운드에서 동일한 이미지 처리를 수행하려고합니다. 나는 안드로이드 서비스로 시작했다. 나는 서비스에서 성공적인 OpenCV의로드 할 수 있습니다이 코드Android 서비스의 OpenCV 이미지 처리

:

import org.opencv.android.BaseLoaderCallback; 
import org.opencv.android.LoaderCallbackInterface; 
import org.opencv.android.OpenCVLoader; 

import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.util.Log; 

public class CameraService extends Service { 

private static final String TAG = "CameraService"; 

BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(CameraService.this) { 

@Override 
public void onManagerConnected(int status) { 
     switch (status) { 
     case LoaderCallbackInterface.SUCCESS: { 
      Log.i("", "OpenCV loaded successfully"); 
     } 
      break; 
     default: { 
      super.onManagerConnected(status); 
     } 
      break; 
     } 
    } 
}; 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if(OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, 
       getApplicationContext(), mLoaderCallback)) { 
     Log.i(TAG, "Loaded OpenCV"); 
    } 
    else 
     Log.i(TAG, "Couldn't load OpenCV"); 
    return super.onStartCommand(intent, flags, startId); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

} 

그러나 나는 내 이전의 활동 onCameraFrame()처럼 프레임을 잡아하는 방법을 몰라? 나는 내게는 CvCameraViewListener2을 암시하지만, 더 이상 보여주고 싶지 않은 CameraBridgeViewBase이 필요하기 때문에 내 서비스에는 내재되어 있지 않습니다. 이렇게 백그라운드에서 이미지 처리를 수행하려면 어떻게해야합니까?

업데이트 -

> 2 난 당신이 나에게 말했다 같은 실행 가능한 프레임을 잡아 덧붙였다. OpenCV를로드하고 카메라에 연결하면 문제가 없습니다. 그러나 프레임을 잡기 전에 그는 프레임을 건너 뛰고 응용 프로그램이 주 스레드에서 너무 많은 작업을하기 때문에 중단합니다.

지금 내 전체 카메라 서비스를 그게 전부 :

public final class MyService extends Service { 

private static final String TAG = MyService.class.getSimpleName(); 
private boolean mStopThread; 
private Thread mThread; 
private VideoCapture mCamera; 
private int mCameraIndex = -1; 

BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { 
    @Override 
    public void onManagerConnected(int status) { 
     switch (status) { 
     case LoaderCallbackInterface.SUCCESS: { 
      Log.i("", "OpenCV loaded successfully"); 

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

     } 
      break; 
     default: { 
      super.onManagerConnected(status); 
     } 
      break; 
     } 
    } 
}; 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if(OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, getApplicationContext(), mLoaderCallback)) 
     Log.i(TAG, "Loaded OpenCV"); 
    else 
     Log.i(TAG, "Couldn't load OpenCV"); 
    return super.onStartCommand(intent, flags, startId); 
} 

public void onDestroy() { 
    this.disconnectCamera(); 
    Log.d(TAG, "onDestroy"); 
    super.onDestroy(); 
} 

private boolean connectCamera(int width, int height) { 
    /* First step - initialize camera connection */ 
    if (!initializeCamera(width, height)) { 
     Log.d(TAG, "initializeCamera failed"); 
     return false; 
    } else { 
     Log.d(TAG, "initializeCamera successfully"); 
    /* 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; 

     /* Select the size that fits surface considering maximum size allowed */ 
     Size frameSize = new Size(width, height); 
     mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, frameSize.width); 
     mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, frameSize.height); 
    } 

    return true; 
} 

private void releaseCamera() { 
    synchronized (this) { 
     if (mCamera != null) { 
      mCamera.release(); 
     } 
    } 
} 

private void disconnectCamera() { 
    // 1. 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; 
    } 
    releaseCamera(); 
} 

private class CameraWorker implements Runnable { 
    public void run() { 
     do { 
      if (!mCamera.grab()) { 
       Log.e(TAG, "Camera frame grab failed"); 
       break; 
      } 
      Log.e(TAG, "Camera frame grabbed"); 
      // img processing 
     } while (!mStopThread); 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; // Not used 
} 
} 

내 로그 :

11-29 12:28:24.370: D/OpenCVManager/Helper(5257): Init finished with status 0 
11-29 12:28:24.370: D/OpenCVManager/Helper(5257): Unbind from service 
11-29 12:28:24.380: D/OpenCVManager/Helper(5257): Calling using callback 
11-29 12:28:24.380: I/(5257): OpenCV loaded successfully 
11-29 12:28:24.380: D/OpenCV::camera(5257): CvCapture_Android::CvCapture_Android(0) 
11-29 12:28:24.440: D/OpenCV_NativeCamera(5257): Connecting to CameraService v 3D 
11-29 12:28:24.670: D/OpenCV_NativeCamera(5257): Instantiated new CameraHandler (0x75e4f29d, 0x71e178b8) 
11-29 12:28:24.750: D/OpenCV_NativeCamera(5257): Starting preview 
11-29 12:28:25.421: E/OpenCV_NativeCamera(5257): CameraHandler::doCall(void*, size_t): cameraCallback returns false (camera connection will be closed) 
11-29 12:28:25.421: E/BufferQueue(5257): [unnamed-5257-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=11 undequeudCount=0) 
11-29 12:28:25.431: E/BufferQueue(5257): [unnamed-5257-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=10 undequeudCount=1) 
11-29 12:28:25.451: D/OpenCV_NativeCamera(5257): Preview started successfully 
11-29 12:28:25.451: D/OpenCV_NativeCamera(5257): CameraHandler::setProperty(0, 640.000000) 
11-29 12:28:25.451: D/OpenCV_NativeCamera(5257): CameraHandler::setProperty(1, 480.000000) 
11-29 12:28:25.451: D/MyService(5257): initializeCamera successfully 
11-29 12:28:25.451: D/MyService(5257): Camera successfully connected 
11-29 12:28:25.451: I/Choreographer(5257): Skipped 86 frames! The application may be doing too much work on its main thread. 
11-29 12:28:25.471: A/libc(5257): @@@ ABORTING: LIBC: HEAP MEMORY CORRUPTION IN tmalloc_small 
11-29 12:28:25.471: A/libc(5257): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 5257() 

무엇이 잘못하고 내가 지금 무엇을 할 수 있습니까?

+0

오류 로그 : 11-28 13 : 19 : 04.095 : E/OpenCV :: camera (2931) : || libnative_camera_r2.3.3.so,하지만 작동합니다. 이 항목을 무시하십시오 – user1755546

+0

그러나 이후 : D/OpenCV_NativeCamera (2931) : CameraService에 연결 v 3D, 아무 일도 일어나지 않습니다. 응용 프로그램은 forzen입니다. – roschulze

+0

기본 예입니다. 카메라에서 프레임을 어떻게 얻습니까? – user1755546

답변

2

네이티브 변형 (VideoCapture)을 사용할 수 있습니다. CameraBridgeViewBase - Android.Camera에서 확장되며 백그라운드에서 작동하지 않습니다.

사용, 카메라에서 프레임을 얻을 수 있습니다 Intefrace의 Runnable : 당신이 예를 찾을 수없는 경우 을 OpenCV-2.4.2에 안드로이드 라이브러리는 예를 얼굴 검출

UPD를 참조

private VideoCapture  mCamera; 

public void run() { 
     Log.i(TAG, "Starting processing thread"); 

    while (true) { 
     Bitmap bmp = null; 

     synchronized (this) { 
      if (mCamera == null) 
       break; 

      if (!mCamera.grab()) { 
       Log.e(TAG, "mCamera.grab() failed"); 
       break; 
      } 

      bmp = processFrame(mCamera); 

     } 

}