From 699216436c575e2ace1abbac11fe7a3bee3320ae Mon Sep 17 00:00:00 2001 From: Ethan Rublee Date: Wed, 22 Sep 2010 12:13:26 +0000 Subject: [PATCH] adding some functionality to the android-opencv shared library --- android/android-jni/Makefile | 2 +- .../src/com/opencv/calibration/Calibrator.java | 124 ++++++++++++++++++ .../src/com/opencv/camera/NativePreviewer.java | 142 ++++++++++++++++----- .../src/com/opencv/opengl/GL2CameraViewer.java | 9 ++ 4 files changed, 243 insertions(+), 34 deletions(-) create mode 100644 android/android-jni/src/com/opencv/calibration/Calibrator.java diff --git a/android/android-jni/Makefile b/android/android-jni/Makefile index 252fde4..8cccd68 100644 --- a/android/android-jni/Makefile +++ b/android/android-jni/Makefile @@ -39,7 +39,7 @@ SWIG_C_OUT = $(SWIG_C_DIR)/android_cv_wrap.cpp LIB = libs/armeabi-v7a/$(LIBNAME) libs/armeabi/$(LIBNAME) -all: $(LIB) +all: $(LIB) nogdb #calls the ndk-build script, passing it OPENCV_ROOT and OPENCV_LIBS_DIR diff --git a/android/android-jni/src/com/opencv/calibration/Calibrator.java b/android/android-jni/src/com/opencv/calibration/Calibrator.java new file mode 100644 index 0000000..42ea11c --- /dev/null +++ b/android/android-jni/src/com/opencv/calibration/Calibrator.java @@ -0,0 +1,124 @@ +package com.opencv.calibration; + + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.locks.ReentrantLock; + +import android.os.AsyncTask; + +import com.opencv.camera.NativeProcessor; +import com.opencv.camera.NativeProcessor.PoolCallback; +import com.opencv.jni.Calibration; +import com.opencv.jni.Size; +import com.opencv.jni.image_pool; + + + +public class Calibrator implements PoolCallback { + private Calibration calibration; + + static public interface CalibrationCallback{ + public void onFoundChessboard(Calibrator calibrator); + public void onDoneCalibration(Calibrator calibration, File calibfile); + public void onFailedChessboard(Calibrator calibrator); + } + private CalibrationCallback callback; + public Calibrator(CalibrationCallback callback) { + calibration = new Calibration(); + this.callback = callback; + } + + public void resetCalibration(){ + calibration.resetChess(); + } + + public void setPatternSize(Size size){ + Size csize = calibration.getPatternsize(); + if(size.getWidth() == csize.getWidth()&& + size.getHeight() == csize.getHeight()) + return; + calibration.setPatternsize(size); + resetCalibration(); + } + public void setPatternSize(int width, int height){ + Size patternsize = new Size(width,height); + setPatternSize(patternsize); + } + + private boolean capture_chess; + + ReentrantLock lock = new ReentrantLock(); + public void calibrate(File calibration_file) throws IOException{ + if(getNumberPatternsDetected() < 3){ + return; + } + CalibrationTask calibtask = new CalibrationTask(calibration_file); + calibtask.execute((Object[])null); + } + + public void queueChessCapture(){ + capture_chess = true; + } + +private class CalibrationTask extends AsyncTask { + File calibfile; + + public CalibrationTask(File calib) throws IOException{ + super(); + calibfile = calib; + calibfile.createNewFile(); + } + + @Override + protected Object doInBackground(Object... params) { + lock.lock(); + try{ + calibration.calibrate(calibfile.getAbsolutePath()); + } + finally{ + lock.unlock(); + } + return null; + + } + + @Override + protected void onPostExecute(Object result) { + callback.onDoneCalibration(Calibrator.this, calibfile); + } + + } + + + @Override + public void process(int idx, image_pool pool, long timestamp, + NativeProcessor nativeProcessor) { + if(lock.tryLock()){ + try{ + if(capture_chess){ + if(calibration.detectAndDrawChessboard(idx, pool)){ + callback.onFoundChessboard(this); + + }else + callback.onFailedChessboard(this); + capture_chess = false; + } + }finally{ + lock.unlock(); + } + } + } + + + public int getNumberPatternsDetected(){ + return calibration.getNumberDetectedChessboards(); + } + + public void setCallback(CalibrationCallback callback) { + this.callback = callback; + + } + + +} diff --git a/android/android-jni/src/com/opencv/camera/NativePreviewer.java b/android/android-jni/src/com/opencv/camera/NativePreviewer.java index b2e5e27..13af609 100644 --- a/android/android-jni/src/com/opencv/camera/NativePreviewer.java +++ b/android/android-jni/src/com/opencv/camera/NativePreviewer.java @@ -9,10 +9,10 @@ import java.util.List; import android.content.Context; import android.graphics.PixelFormat; import android.hardware.Camera; -import android.hardware.Camera.Parameters; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.Size; import android.os.Handler; +import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; @@ -31,9 +31,26 @@ public class NativePreviewer extends SurfaceView implements private int pixelformat; private PixelFormat pixelinfo; + public NativePreviewer(Context context,AttributeSet attributes){ + super(context,attributes); + listAllCameraMethods(); + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed. + mHolder = getHolder(); + mHolder.addCallback(this); + mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + + this.preview_width = attributes.getAttributeIntValue("opencv", "preview_width", 600); + this.preview_height= attributes.getAttributeIntValue("opencv", "preview_height", 600); + + processor = new NativeProcessor(); + + setZOrderMediaOverlay(false); + } public NativePreviewer(Context context, int preview_width, int preview_height) { super(context); + listAllCameraMethods(); // Install a SurfaceHolder.Callback so we get notified when the @@ -46,40 +63,73 @@ public class NativePreviewer extends SurfaceView implements this.preview_height = preview_height; processor = new NativeProcessor(); + setZOrderMediaOverlay(false); } - - public void surfaceCreated(SurfaceHolder holder) { - - // The Surface has been created, acquire the camera and tell it where - // to draw. - mCamera = Camera.open(); - try { - mCamera.setPreviewDisplay(holder); - } catch (IOException exception) { - mCamera.release(); - mCamera = null; - + Handler camerainiter = new Handler(); + void initCamera(SurfaceHolder holder) throws InterruptedException{ + if(mCamera == null){ + // The Surface has been created, acquire the camera and tell it where + // to draw. + int i = 0; + while(i++ < 5){ + try{ + mCamera = Camera.open(); + break; + }catch(RuntimeException e){ + Thread.sleep(200); + } + } + try { + mCamera.setPreviewDisplay(holder); + } catch (IOException exception) { + mCamera.release(); + mCamera = null; + + }catch(RuntimeException e){ + Log.e("camera", "stacktrace", e); + } } - } - - public void surfaceDestroyed(SurfaceHolder holder) { - // Surface will be destroyed when we return, so stop the preview. - // Because the CameraDevice object is not a shared resource, it's very - // important to release it when the activity is paused. - mCamera.stopPreview(); - mCamera.release(); + void releaseCamera(){ + if(mCamera !=null){ + // Surface will be destroyed when we return, so stop the preview. + // Because the CameraDevice object is not a shared resource, it's very + // important to release it when the activity is paused. + mCamera.stopPreview(); + mCamera.release(); + } // processor = null; mCamera = null; mAcb = null; mPCWB = null; + } + + public void surfaceCreated(SurfaceHolder holder) { + + + + } + + public void surfaceDestroyed(SurfaceHolder holder) { + + releaseCamera(); } + private boolean hasAutoFocus = false; public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + try { + initCamera(mHolder); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + + // Now that the size is known, set up the camera parameters and begin // the preview. @@ -95,6 +145,27 @@ public class NativePreviewer extends SurfaceView implements } preview_width = best_width; preview_height = best_height; + List fmodes = mCamera.getParameters().getSupportedFocusModes(); + + + int idx = fmodes.indexOf(Camera.Parameters.FOCUS_MODE_INFINITY); + if(idx != -1){ + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); + }else if(fmodes.indexOf(Camera.Parameters.FOCUS_MODE_FIXED) != -1){ + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED); + } + + if(fmodes.indexOf(Camera.Parameters.FOCUS_MODE_AUTO) != -1){ + hasAutoFocus = true; + } + + List scenemodes = mCamera.getParameters().getSupportedSceneModes(); + if(scenemodes != null) + if(scenemodes.indexOf(Camera.Parameters.SCENE_MODE_STEADYPHOTO) != -1){ + parameters.setSceneMode(Camera.Parameters.SCENE_MODE_STEADYPHOTO); + } + + parameters.setPreviewSize(preview_width, preview_height); @@ -123,13 +194,14 @@ public class NativePreviewer extends SurfaceView implements mCamera.startPreview(); - postautofocus(0); + //postautofocus(0); } public void postautofocus(int delay) { - handler.postDelayed(autofocusrunner, delay); + if(hasAutoFocus) + handler.postDelayed(autofocusrunner, delay); } - Runnable autofocusrunner = new Runnable() { + private Runnable autofocusrunner = new Runnable() { @Override public void run() { @@ -143,14 +215,7 @@ public class NativePreviewer extends SurfaceView implements @Override public void onAutoFocus(boolean success, Camera camera) { if(!success) - postautofocus(1000); - else{ - Parameters params = camera.getParameters(); - params.setSceneMode(Parameters.SCENE_MODE_AUTO); - camera.setParameters(params); - } - - + postautofocus(1000); } }; Handler handler = new Handler(); @@ -321,14 +386,25 @@ public class NativePreviewer extends SurfaceView implements * */ public void onPause() { + + releaseCamera(); + addCallbackStack(null); + processor.stop(); - mCamera.stopPreview(); + + + + } public void onResume() { + + processor.start(); + + } } \ No newline at end of file diff --git a/android/android-jni/src/com/opencv/opengl/GL2CameraViewer.java b/android/android-jni/src/com/opencv/opengl/GL2CameraViewer.java index 837470c..2498ad7 100644 --- a/android/android-jni/src/com/opencv/opengl/GL2CameraViewer.java +++ b/android/android-jni/src/com/opencv/opengl/GL2CameraViewer.java @@ -46,6 +46,7 @@ import com.opencv.jni.image_pool; import android.content.Context; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; +import android.util.AttributeSet; import android.util.Log; @@ -87,14 +88,22 @@ public class GL2CameraViewer extends GLSurfaceView{ } }; + public GL2CameraViewer(Context context,AttributeSet attributeSet) { + super(context,attributeSet); + + init(false, 0, 0); + setZOrderMediaOverlay(true); + } public GL2CameraViewer(Context context) { super(context); init(false, 0, 0); + setZOrderMediaOverlay(true); } public GL2CameraViewer(Context context, boolean translucent, int depth, int stencil) { super(context); init(translucent, depth, stencil); + setZOrderMediaOverlay(true); } private void init(boolean translucent, int depth, int stencil) { -- 2.7.4