diff --git a/samples/android/color-blob-detection/res/layout/color_blob_detection_surface_view.xml b/samples/android/color-blob-detection/res/layout/color_blob_detection_surface_view.xml
new file mode 100644
index 000000000..f31d0460e
--- /dev/null
+++ b/samples/android/color-blob-detection/res/layout/color_blob_detection_surface_view.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
index 2ee10135f..ccba0a194 100644
--- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
+++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
@@ -1,62 +1,53 @@
package org.opencv.samples.colorblobdetect;
+import java.util.List;
+
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.MatOfPoint;
+import org.opencv.core.Rect;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.framework.OpenCvCameraBridgeViewBase.CvCameraViewListener;
+import org.opencv.framework.OpenCvJavaCameraView;
+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.MotionEvent;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.view.View.OnTouchListener;
-public class ColorBlobDetectionActivity extends Activity {
- private static final String TAG = "OCVSample::Activity";
+public class ColorBlobDetectionActivity extends Activity implements OnTouchListener, CvCameraViewListener {
+ private static final String TAG = "OCVSample::Activity";
- private ColorBlobDetectionView mView;
+ private boolean mIsColorSelected = false;
+ private Mat mRgba;
+ private Scalar mBlobColorRgba;
+ private Scalar mBlobColorHsv;
+ private ColorBlobDetector mDetector;
+ private Mat mSpectrum;
+ private Size SPECTRUM_SIZE;
+ private Scalar CONTOUR_COLOR;
- private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
+ private OpenCvJavaCameraView mOpenCvCameraView;
+
+ 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 ColorBlobDetectionView(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();
+ mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
} break;
default:
{
@@ -70,25 +61,6 @@ public class ColorBlobDetectionActivity 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) {
@@ -96,5 +68,117 @@ public class ColorBlobDetectionActivity extends Activity {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ setContentView(R.layout.color_blob_detection_surface_view);
+
+ mOpenCvCameraView = (OpenCvJavaCameraView)findViewById(R.id.color_blob_detection_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);
+ mDetector = new ColorBlobDetector();
+ mSpectrum = new Mat();
+ mBlobColorRgba = new Scalar(255);
+ mBlobColorHsv = new Scalar(255);
+ SPECTRUM_SIZE = new Size(200, 32);
+ CONTOUR_COLOR = new Scalar(255,0,0,255);
+ }
+
+ public void onCameraViewStopped() {
+ mRgba.release();
+ }
+
+ public boolean onTouch(View v, MotionEvent event) {
+ int cols = mRgba.cols();
+ int rows = mRgba.rows();
+
+ int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
+ int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
+
+ int x = (int)event.getX() - xOffset;
+ int y = (int)event.getY() - yOffset;
+
+ Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
+
+ if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
+
+ Rect touchedRect = new Rect();
+
+ touchedRect.x = (x>4) ? x-4 : 0;
+ touchedRect.y = (y>4) ? y-4 : 0;
+
+ touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
+ touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
+
+ Mat touchedRegionRgba = mRgba.submat(touchedRect);
+
+ Mat touchedRegionHsv = new Mat();
+ Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
+
+ // Calculate average color of touched region
+ mBlobColorHsv = Core.sumElems(touchedRegionHsv);
+ int pointCount = touchedRect.width*touchedRect.height;
+ for (int i = 0; i < mBlobColorHsv.val.length; i++)
+ mBlobColorHsv.val[i] /= pointCount;
+
+ mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
+
+ Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
+ ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
+
+ mDetector.setHsvColor(mBlobColorHsv);
+
+ Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
+
+ mIsColorSelected = true;
+
+ return false; // don't need subsequent touch events
+ }
+
+ public Mat onCameraFrame(Mat inputFrame) {
+ inputFrame.copyTo(mRgba);
+
+ if (mIsColorSelected) {
+ mDetector.process(mRgba);
+ List contours = mDetector.getContours();
+ Log.e(TAG, "Contours count: " + contours.size());
+ Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
+
+ Mat colorLabel = mRgba.submat(2, 34, 2, 34);
+ colorLabel.setTo(mBlobColorRgba);
+
+ Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols());
+ mSpectrum.copyTo(spectrumLabel);
+ }
+
+ return mRgba;
+ }
+
+ private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
+ Mat pointMatRgba = new Mat();
+ Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
+ Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
+
+ return new Scalar(pointMatRgba.get(0, 0));
}
}
\ No newline at end of file
diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java
deleted file mode 100644
index 6ad57daa3..000000000
--- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.opencv.samples.colorblobdetect;
-
-import java.util.List;
-import org.opencv.android.Utils;
-import org.opencv.core.Core;
-import org.opencv.core.CvType;
-import org.opencv.core.Mat;
-import org.opencv.core.MatOfPoint;
-import org.opencv.core.Rect;
-import org.opencv.core.Scalar;
-import org.opencv.core.Size;
-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.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.View.OnTouchListener;
-
-public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchListener {
- private static final String TAG = "OCVSample::View";
-
- private Mat mRgba;
- private boolean mIsColorSelected = false;
- private Scalar mBlobColorRgba = new Scalar(255);
- private Scalar mBlobColorHsv = new Scalar(255);
- private ColorBlobDetector mDetector = new ColorBlobDetector();
- private Mat mSpectrum = new Mat();
- private static Size SPECTRUM_SIZE = new Size(200, 32);
- private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255);
-
-
- public ColorBlobDetectionView(Context context) {
- super(context);
- setOnTouchListener(this);
- Log.i(TAG, "Instantiated new " + this.getClass());
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.i(TAG, "called surfaceCreated");
- synchronized (this) {
- // initialize Mat before usage
- mRgba = new Mat();
- }
-
- super.surfaceCreated(holder);
- }
-
- private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
- Mat pointMatRgba = new Mat();
- Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
- Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
-
- return new Scalar(pointMatRgba.get(0, 0));
- }
-
- public boolean onTouch(View v, MotionEvent event) {
- int cols = mRgba.cols();
- int rows = mRgba.rows();
-
- int xOffset = (getWidth() - cols) / 2;
- int yOffset = (getHeight() - rows) / 2;
-
- int x = (int)event.getX() - xOffset;
- int y = (int)event.getY() - yOffset;
-
- Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
-
- if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
-
- Rect touchedRect = new Rect();
-
- touchedRect.x = (x>4) ? x-4 : 0;
- touchedRect.y = (y>4) ? y-4 : 0;
-
- touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
- touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
-
- Mat touchedRegionRgba = mRgba.submat(touchedRect);
-
- Mat touchedRegionHsv = new Mat();
- Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
-
- // Calculate average color of touched region
- mBlobColorHsv = Core.sumElems(touchedRegionHsv);
- int pointCount = touchedRect.width*touchedRect.height;
- for (int i = 0; i < mBlobColorHsv.val.length; i++)
- mBlobColorHsv.val[i] /= pointCount;
-
- mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
-
- Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
- ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
-
- mDetector.setHsvColor(mBlobColorHsv);
-
- Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
-
- mIsColorSelected = true;
-
- return false; // don't need subsequent touch events
- }
-
- @Override
- protected Bitmap processFrame(VideoCapture capture) {
- capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
-
- Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
-
- if (mIsColorSelected) {
- mDetector.process(mRgba);
- List contours = mDetector.getContours();
- Log.e(TAG, "Contours count: " + contours.size());
- Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
-
- Mat colorLabel = mRgba.submat(2, 34, 2, 34);
- colorLabel.setTo(mBlobColorRgba);
-
- Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols());
- mSpectrum.copyTo(spectrumLabel);
- }
-
- try {
- Utils.matToBitmap(mRgba, bmp);
- } catch(Exception e) {
- Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
- bmp.recycle();
- bmp = null;
- }
-
- return bmp;
- }
-
- @Override
- public void run() {
- super.run();
-
- synchronized (this) {
- // Explicitly deallocate Mats
- if (mRgba != null)
- mRgba.release();
-
- mRgba = null;
- }
- }
-}
diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/SampleCvViewBase.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/SampleCvViewBase.java
deleted file mode 100644
index 47cc3c85a..000000000
--- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/SampleCvViewBase.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.opencv.samples.colorblobdetect;
-
-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