diff --git a/samples/android/tutorial-2-opencvcamera/res/layout/tutorial2_surface_view.xml b/samples/android/tutorial-2-opencvcamera/res/layout/tutorial2_surface_view.xml
new file mode 100644
index 0000000000..b8871e037c
--- /dev/null
+++ b/samples/android/tutorial-2-opencvcamera/res/layout/tutorial2_surface_view.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2NativeCamera.java b/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2NativeCamera.java
index 67a2c755fb..c23cc7dc6e 100644
--- a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2NativeCamera.java
+++ b/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2NativeCamera.java
@@ -3,10 +3,17 @@ package org.opencv.samples.tutorial2;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.framework.OpenCvJavaCameraView;
+import org.opencv.framework.OpenCvCameraBridgeViewBase.CvCameraViewListener;
+import org.opencv.highgui.Highgui;
+import org.opencv.imgproc.Imgproc;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
@@ -14,60 +21,30 @@ import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
-public class Sample2NativeCamera extends Activity {
+public class Sample2NativeCamera extends Activity implements CvCameraViewListener {
private static final String TAG = "OCVSample::Activity";
public static final int VIEW_MODE_RGBA = 0;
public static final int VIEW_MODE_GRAY = 1;
public static final int VIEW_MODE_CANNY = 2;
+ private static int viewMode = VIEW_MODE_RGBA;
private MenuItem mItemPreviewRGBA;
private MenuItem mItemPreviewGray;
private MenuItem mItemPreviewCanny;
- private Sample2View mView;
+ private Mat mRgba;
+ private Mat mIntermediateMat;
- public static int viewMode = VIEW_MODE_RGBA;
+ private OpenCvJavaCameraView mOpenCvCameraView;
- private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
+ private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
- // Create and set View
- mView = new Sample2View(mAppContext);
- setContentView(mView);
-
- // Check native OpenCV camera
- if( !mView.openCamera() ) {
- AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
- ad.setCancelable(false); // This blocks the 'BACK' button
- ad.setMessage("Fatal error: can't open camera!");
- ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- finish();
- }
- });
- ad.show();
- }
- } break;
-
- /** OpenCV loader cannot start Google Play **/
- case LoaderCallbackInterface.MARKET_ERROR:
- {
- Log.d(TAG, "Google Play service is not accessible!");
- AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
- MarketErrorMessage.setTitle("OpenCV Manager");
- MarketErrorMessage.setMessage("Google Play service is not accessible!\nTry to install the 'OpenCV Manager' and the appropriate 'OpenCV binary pack' APKs from OpenCV SDK manually via 'adb install' command.");
- MarketErrorMessage.setCancelable(false); // This blocks the 'BACK' button
- MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
- MarketErrorMessage.show();
+ mOpenCvCameraView.enableView();
} break;
default:
{
@@ -81,25 +58,6 @@ public class Sample2NativeCamera extends Activity {
Log.i(TAG, "Instantiated new " + this.getClass());
}
- @Override
- protected void onPause() {
- Log.i(TAG, "called onPause");
- if (null != mView)
- mView.releaseCamera();
- super.onPause();
- }
-
- @Override
- protected void onResume() {
- Log.i(TAG, "called onResume");
- super.onResume();
-
- Log.i(TAG, "Trying to load OpenCV library");
- if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) {
- Log.e(TAG, "Cannot connect to OpenCV Manager");
- }
- }
-
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -107,6 +65,61 @@ public class Sample2NativeCamera extends Activity {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ setContentView(R.layout.tutorial2_surface_view);
+
+ mOpenCvCameraView = (OpenCvJavaCameraView)findViewById(R.id.tutorial2_activity_surface_view);
+ mOpenCvCameraView.setCvCameraViewListener(this);
+ }
+
+ @Override
+ public void onPause()
+ {
+ mOpenCvCameraView.disableView();
+ super.onPause();
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback);
+ }
+
+ public void onDestroy() {
+ super.onDestroy();
+ mOpenCvCameraView.disableView();
+ }
+
+ public void onCameraViewStarted(int width, int height) {
+ mRgba = new Mat(height, width, CvType.CV_8UC4);
+ mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
+ }
+
+ public void onCameraViewStopped() {
+ mRgba.release();
+ mIntermediateMat.release();
+ }
+
+ public Mat onCameraFrame(Mat inputFrame) {
+ switch (Sample2NativeCamera.viewMode) {
+ case Sample2NativeCamera.VIEW_MODE_GRAY:
+ {
+ Imgproc.cvtColor(inputFrame, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
+ } break;
+ case Sample2NativeCamera.VIEW_MODE_RGBA:
+ {
+ inputFrame.copyTo(mRgba);
+ Core.putText(mRgba, "OpenCV+Android", new Point(10, 50), 3, 1, new Scalar(255, 0, 0, 255), 2);
+ } break;
+ case Sample2NativeCamera.VIEW_MODE_CANNY:
+ {
+ Imgproc.Canny(inputFrame, mIntermediateMat, 80, 100);
+ Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
+ } break;
+ }
+
+ return mRgba;
}
@Override
@@ -122,11 +135,21 @@ public class Sample2NativeCamera extends Activity {
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item == mItemPreviewRGBA)
+ {
+ mOpenCvCameraView.SetCaptureFormat(Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
viewMode = VIEW_MODE_RGBA;
+ }
else if (item == mItemPreviewGray)
+ {
+ mOpenCvCameraView.SetCaptureFormat(Highgui.CV_CAP_ANDROID_GREY_FRAME);
viewMode = VIEW_MODE_GRAY;
+ }
else if (item == mItemPreviewCanny)
+ {
+ mOpenCvCameraView.SetCaptureFormat(Highgui.CV_CAP_ANDROID_GREY_FRAME);
viewMode = VIEW_MODE_CANNY;
+ }
+
return true;
}
}
diff --git a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2View.java b/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2View.java
deleted file mode 100644
index e61dd4043e..0000000000
--- a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2View.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.opencv.samples.tutorial2;
-
-import org.opencv.android.Utils;
-import org.opencv.core.Core;
-import org.opencv.core.Mat;
-import org.opencv.core.Point;
-import org.opencv.core.Scalar;
-import org.opencv.highgui.Highgui;
-import org.opencv.highgui.VideoCapture;
-import org.opencv.imgproc.Imgproc;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-class Sample2View extends SampleCvViewBase {
- private static final String TAG = "OCVSample::View";
-
- private Mat mRgba;
- private Mat mGray;
- private Mat mIntermediateMat;
-
- public Sample2View(Context context) {
- super(context);
- Log.i(TAG, "Instantiated new " + this.getClass());
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.i(TAG, "called surfaceCreated");
- synchronized (this) {
- // initialize Mats before usage
- mGray = new Mat();
- mRgba = new Mat();
- mIntermediateMat = new Mat();
- }
-
- super.surfaceCreated(holder);
- }
-
- @Override
- protected Bitmap processFrame(VideoCapture capture) {
- switch (Sample2NativeCamera.viewMode) {
- case Sample2NativeCamera.VIEW_MODE_GRAY:
- capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
- Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
- break;
- case Sample2NativeCamera.VIEW_MODE_RGBA:
- capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
- Core.putText(mRgba, "OpenCV+Android", new Point(10, 50), 3, 1, new Scalar(255, 0, 0, 255), 2);
- break;
- case Sample2NativeCamera.VIEW_MODE_CANNY:
- capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
- Imgproc.Canny(mGray, mIntermediateMat, 80, 100);
- Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
- break;
- }
-
- Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
-
- try {
- Utils.matToBitmap(mRgba, bmp);
- return bmp;
- } catch(Exception e) {
- Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
- bmp.recycle();
- return null;
- }
- }
-
- @Override
- public void run() {
- super.run();
-
- synchronized (this) {
- // Explicitly deallocate Mats
- if (mRgba != null)
- mRgba.release();
- if (mGray != null)
- mGray.release();
- if (mIntermediateMat != null)
- mIntermediateMat.release();
-
- mRgba = null;
- mGray = null;
- mIntermediateMat = null;
- }
- }
-}
diff --git a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/SampleCvViewBase.java b/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/SampleCvViewBase.java
deleted file mode 100644
index 76924570ee..0000000000
--- a/samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/SampleCvViewBase.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.opencv.samples.tutorial2;
-
-import java.util.List;
-
-import org.opencv.core.Size;
-import org.opencv.highgui.VideoCapture;
-import org.opencv.highgui.Highgui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable {
- private static final String TAG = "OCVSample::BaseView";
-
- private SurfaceHolder mHolder;
- private VideoCapture mCamera;
-
- public SampleCvViewBase(Context context) {
- super(context);
- mHolder = getHolder();
- mHolder.addCallback(this);
- Log.i(TAG, "Instantiated new " + this.getClass());
- }
-
- public synchronized boolean openCamera() {
- Log.i(TAG, "Opening Camera");
- mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
- if (!mCamera.isOpened()) {
- releaseCamera();
- Log.e(TAG, "Can't open native camera");
- return false;
- }
- return true;
- }
-
- public synchronized void releaseCamera() {
- Log.i(TAG, "Releasing Camera");
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
-
- public synchronized void setupCamera(int width, int height) {
- if (mCamera != null && mCamera.isOpened()) {
- Log.i(TAG, "Setup Camera - " + width + "x" + height);
- List sizes = mCamera.getSupportedPreviewSizes();
- int mFrameWidth = width;
- int mFrameHeight = height;
-
- // selecting optimal camera preview size
- {
- double minDiff = Double.MAX_VALUE;
- for (Size size : sizes) {
- if (Math.abs(size.height - height) < minDiff) {
- mFrameWidth = (int) size.width;
- mFrameHeight = (int) size.height;
- minDiff = Math.abs(size.height - height);
- }
- }
- }
-
- mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth);
- mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight);
- }
- }
-
- public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
- Log.i(TAG, "called surfaceChanged");
- setupCamera(width, height);
- }
-
- public void surfaceCreated(SurfaceHolder holder) {
- Log.i(TAG, "called surfaceCreated");
- (new Thread(this)).start();
- }
-
- public void surfaceDestroyed(SurfaceHolder holder) {
- Log.i(TAG, "called surfaceDestroyed");
- }
-
- protected abstract Bitmap processFrame(VideoCapture capture);
-
- public void run() {
- Log.i(TAG, "Started 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);
- }
-
- if (bmp != null) {
- Canvas canvas = mHolder.lockCanvas();
- if (canvas != null) {
- canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
- canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
- mHolder.unlockCanvasAndPost(canvas);
- }
- bmp.recycle();
- }
- }
- Log.i(TAG, "Finished processing thread");
- }
-}
\ No newline at end of file