Fix Andoid samples: black screen after resume problem

pull/12/merge
Andrey Kamaev 12 years ago
parent 71df8906be
commit 285af48040
  1. 31
      samples/android/15-puzzle/src/org/opencv/samples/puzzle15/SampleCvViewBase.java
  2. 145
      samples/android/15-puzzle/src/org/opencv/samples/puzzle15/puzzle15Activity.java
  3. 72
      samples/android/15-puzzle/src/org/opencv/samples/puzzle15/puzzle15View.java
  4. 153
      samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
  5. 126
      samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java
  6. 168
      samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java
  7. 37
      samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/SampleCvViewBase.java
  8. 2
      samples/android/face-detection/jni/Android.mk
  9. 196
      samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp
  10. 2
      samples/android/face-detection/jni/DetectionBasedTracker_jni.h
  11. 83
      samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java
  12. 170
      samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java
  13. 107
      samples/android/face-detection/src/org/opencv/samples/fd/FdView.java
  14. 29
      samples/android/face-detection/src/org/opencv/samples/fd/SampleCvViewBase.java
  15. 140
      samples/android/image-manipulations/src/org/opencv/samples/imagemanipulations/ImageManipulationsActivity.java
  16. 76
      samples/android/image-manipulations/src/org/opencv/samples/imagemanipulations/ImageManipulationsView.java
  17. 29
      samples/android/image-manipulations/src/org/opencv/samples/imagemanipulations/SampleCvViewBase.java
  18. 50
      samples/android/tutorial-0-androidcamera/src/org/opencv/samples/tutorial0/Sample0Base.java
  19. 77
      samples/android/tutorial-0-androidcamera/src/org/opencv/samples/tutorial0/Sample0View.java
  20. 36
      samples/android/tutorial-0-androidcamera/src/org/opencv/samples/tutorial0/SampleViewBase.java
  21. 143
      samples/android/tutorial-1-addopencv/src/org/opencv/samples/tutorial1/Sample1Java.java
  22. 40
      samples/android/tutorial-1-addopencv/src/org/opencv/samples/tutorial1/Sample1View.java
  23. 40
      samples/android/tutorial-1-addopencv/src/org/opencv/samples/tutorial1/SampleViewBase.java
  24. 139
      samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2NativeCamera.java
  25. 8
      samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/Sample2View.java
  26. 33
      samples/android/tutorial-2-opencvcamera/src/org/opencv/samples/tutorial2/SampleCvViewBase.java
  27. 143
      samples/android/tutorial-3-native/src/org/opencv/samples/tutorial3/Sample3Native.java
  28. 40
      samples/android/tutorial-3-native/src/org/opencv/samples/tutorial3/Sample3View.java
  29. 38
      samples/android/tutorial-3-native/src/org/opencv/samples/tutorial3/SampleViewBase.java
  30. 155
      samples/android/tutorial-4-mixed/src/org/opencv/samples/tutorial4/Sample4Mixed.java
  31. 38
      samples/android/tutorial-4-mixed/src/org/opencv/samples/tutorial4/Sample4View.java
  32. 40
      samples/android/tutorial-4-mixed/src/org/opencv/samples/tutorial4/SampleViewBase.java

@ -14,7 +14,7 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable { public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private static final String TAG = "Sample::SurfaceView"; private static final String TAG = "Sample-15puzzle::SurfaceView";
private SurfaceHolder mHolder; private SurfaceHolder mHolder;
private VideoCapture mCamera; private VideoCapture mCamera;
@ -29,28 +29,27 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
synchronized (this) { synchronized (this) {
releaseCamera(); releaseCamera();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) { if (!mCamera.isOpened()) {
mCamera.release(); releaseCamera();
mCamera = null; Log.e(TAG, "Failed to open native camera");
Log.e(TAG, "Failed to open native camera"); return false;
return false; }
} }
}
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
} }
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera("+width+", "+height+")"); Log.i(TAG, "setupCamera("+width+", "+height+")");
synchronized (this) { synchronized (this) {
@ -77,7 +76,7 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -12,107 +12,96 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
/** Activity class implements LoaderCallbackInterface to handle OpenCV initialization status **/ /** Activity class implements LoaderCallbackInterface to handle OpenCV initialization status **/
public class puzzle15Activity extends Activity public class puzzle15Activity extends Activity
{ {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
private MenuItem mItemNewGame; private MenuItem mItemNewGame;
private MenuItem mItemToggleNumbers; private MenuItem mItemToggleNumbers;
private puzzle15View mView = null; private puzzle15View mView = null;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Create and set View // Create and set View
mView = new puzzle15View(mAppContext); mView = new puzzle15View(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public puzzle15Activity() public puzzle15Activity() {
{
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( mView!=null && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState) {
{
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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");
}
} }
@Override @Override

@ -18,7 +18,7 @@ import android.view.View;
import android.view.View.OnTouchListener; import android.view.View.OnTouchListener;
public class puzzle15View extends SampleCvViewBase implements OnTouchListener { public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
private Mat mRgba; private Mat mRgba;
private Mat mRgba15; private Mat mRgba15;
private Mat[] mCells; private Mat[] mCells;
private Mat[] mCells15; private Mat[] mCells15;
@ -45,13 +45,13 @@ public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
} }
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) { synchronized (this) {
// initialize Mat before usage // initialize Mat before usage
mRgba = new Mat(); mRgba = new Mat();
} }
super.surfaceCreated(holder); super.surfaceCreated(holder);
} }
public static void shuffle(int[] array) { public static void shuffle(int[] array) {
for (int i = array.length; i > 1; i--) { for (int i = array.length; i > 1; i--) {
@ -83,11 +83,11 @@ public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
return sum % 2 == 0; return sum % 2 == 0;
} }
private void createPuzzle(int cols, int rows) { private void createPuzzle(int cols, int rows, int type) {
mCells = new Mat[gridArea]; mCells = new Mat[gridArea];
mCells15 = new Mat[gridArea]; mCells15 = new Mat[gridArea];
mRgba15 = new Mat(rows, cols, mRgba.type()); mRgba15 = new Mat(rows, cols, type);
mIndexses = new int[gridArea]; mIndexses = new int[gridArea];
for (int i = 0; i < gridSize; i++) { for (int i = 0; i < gridSize; i++) {
@ -117,12 +117,16 @@ public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
int cols = mRgba.cols(); int cols = mRgba.cols();
int rows = mRgba.rows(); int rows = mRgba.rows();
rows = rows - rows%4; rows = rows - rows%4;
cols = cols - cols%4; cols = cols - cols%4;
if (mCells == null) if (mCells == null)
createPuzzle(cols, rows); createPuzzle(cols, rows, mRgba.type());
else if(mRgba15.cols() != cols || mRgba15.rows() != rows) {
releaseMats();
createPuzzle(cols, rows, mRgba.type());
}
// copy shuffled tiles // copy shuffled tiles
for (int i = 0; i < gridArea; i++) { for (int i = 0; i < gridArea; i++) {
@ -141,10 +145,10 @@ public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
drawGrid(cols, rows); drawGrid(cols, rows);
Bitmap bmp = Bitmap.createBitmap(cols, rows, Bitmap.Config.ARGB_8888); Bitmap bmp = Bitmap.createBitmap(cols, rows, Bitmap.Config.ARGB_8888);
try { try {
Utils.matToBitmap(mRgba15, bmp); Utils.matToBitmap(mRgba15, bmp);
return bmp; return bmp;
} catch(Exception e) { } catch(Exception e) {
Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage()); Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle(); bmp.recycle();
return null; return null;
} }
@ -162,32 +166,38 @@ public class puzzle15View extends SampleCvViewBase implements OnTouchListener {
super.run(); super.run();
synchronized (this) { synchronized (this) {
// Explicitly deallocate Mats releaseMats();
if (mCells != null) {
for (Mat m : mCells)
m.release();
}
if (mCells15 != null) {
for (Mat m : mCells15)
m.release();
}
if (mRgba != null) if (mRgba != null)
mRgba.release(); mRgba.release();
if (mRgba15 != null)
mRgba15.release();
mRgba = null; mRgba = null;
mRgba15 = null;
mCells = null;
mCells15 = null;
mIndexses = null;
} }
} }
private void releaseMats() {
// Explicitly deallocate Mats
if (mCells != null) {
for (Mat m : mCells)
m.release();
}
if (mCells15 != null) {
for (Mat m : mCells15)
m.release();
}
if (mRgba15 != null)
mRgba15.release();
mRgba15 = null;
mCells = null;
mCells15 = null;
mIndexses = null;
}
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
if(mRgba==null) return false; if(mRgba==null) return false;
int cols = mRgba.cols(); int cols = mRgba.cols();
int rows = mRgba.rows(); int rows = mRgba.rows();
float xoffset = (getWidth() - cols) / 2; float xoffset = (getWidth() - cols) / 2;
float yoffset = (getHeight() - rows) / 2; float yoffset = (getHeight() - rows) / 2;

@ -10,101 +10,90 @@ import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class ColorBlobDetectionActivity extends Activity { public class ColorBlobDetectionActivity extends Activity {
private static final String TAG = "Example/ColorBlobDetection"; private static final String TAG = "Sample-ColorBlobDetection::Activity";
private ColorBlobDetectionView mView; private ColorBlobDetectionView mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Create and set View // Create and set View
mView = new ColorBlobDetectionView(mAppContext); mView = new ColorBlobDetectionView(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public ColorBlobDetectionActivity() public ColorBlobDetectionActivity() {
{ Log.i(TAG, "Instantiated new " + this.getClass());
Log.i(TAG, "Instantiated new " + this.getClass()); }
}
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( (null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
Log.i(TAG, "Trying to load OpenCV library"); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
{
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
} }
} }

@ -23,127 +23,121 @@ import android.view.View.OnTouchListener;
public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchListener { public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchListener {
private Mat mRgba; private Mat mRgba;
private boolean mIsColorSelected = false; private boolean mIsColorSelected = false;
private Scalar mBlobColorRgba = new Scalar(255); private Scalar mBlobColorRgba = new Scalar(255);
private Scalar mBlobColorHsv = new Scalar(255); private Scalar mBlobColorHsv = new Scalar(255);
private ColorBlobDetector mDetector = new ColorBlobDetector(); private ColorBlobDetector mDetector = new ColorBlobDetector();
private Mat mSpectrum = new Mat(); private Mat mSpectrum = new Mat();
private static Size SPECTRUM_SIZE = new Size(200, 32); private static Size SPECTRUM_SIZE = new Size(200, 32);
// Logcat tag // Logcat tag
private static final String TAG = "Example/ColorBlobDetection"; private static final String TAG = "Sample-ColorBlobDetection::View";
private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255); private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255);
public ColorBlobDetectionView(Context context) public ColorBlobDetectionView(Context context) {
{
super(context); super(context);
setOnTouchListener(this); setOnTouchListener(this);
} }
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) { synchronized (this) {
// initialize Mat before usage // initialize Mat before usage
mRgba = new Mat(); mRgba = new Mat();
} }
super.surfaceCreated(holder); super.surfaceCreated(holder);
} }
public boolean onTouch(View v, MotionEvent event) public boolean onTouch(View v, MotionEvent event) {
{
int cols = mRgba.cols(); int cols = mRgba.cols();
int rows = mRgba.rows(); int rows = mRgba.rows();
int xOffset = (getWidth() - cols) / 2; int xOffset = (getWidth() - cols) / 2;
int yOffset = (getHeight() - rows) / 2; int yOffset = (getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset; int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset; int y = (int)event.getY() - yOffset;
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")"); Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false; if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
Rect touchedRect = new Rect(); Rect touchedRect = new Rect();
touchedRect.x = (x>4) ? x-4 : 0; touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0; touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x; touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y; touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
Mat touchedRegionRgba = mRgba.submat(touchedRect); Mat touchedRegionRgba = mRgba.submat(touchedRect);
Mat touchedRegionHsv = new Mat(); Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL); Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
// Calculate average color of touched region // Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv); mBlobColorHsv = Core.sumElems(touchedRegionHsv);
int pointCount = touchedRect.width*touchedRect.height; int pointCount = touchedRect.width*touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++) for (int i = 0; i < mBlobColorHsv.val.length; i++)
{ mBlobColorHsv.val[i] /= pointCount;
mBlobColorHsv.val[i] /= pointCount;
}
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv); mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")"); ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
mDetector.setHsvColor(mBlobColorHsv); mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE); Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
mIsColorSelected = true; mIsColorSelected = true;
return false; // don't need subsequent touch events return false; // don't need subsequent touch events
} }
@Override
protected Bitmap processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
@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); Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
if (mIsColorSelected) if (mIsColorSelected) {
{ mDetector.process(mRgba);
mDetector.process(mRgba); List<MatOfPoint> contours = mDetector.getContours();
List<MatOfPoint> contours = mDetector.getContours();
Log.e(TAG, "Contours count: " + contours.size()); Log.e(TAG, "Contours count: " + contours.size());
Core.drawContours(mRgba, contours, -1, CONTOUR_COLOR); Core.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
Mat colorLabel = mRgba.submat(2, 34, 2, 34); Mat colorLabel = mRgba.submat(2, 34, 2, 34);
colorLabel.setTo(mBlobColorRgba); colorLabel.setTo(mBlobColorRgba);
Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols()); Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols());
mSpectrum.copyTo(spectrumLabel); mSpectrum.copyTo(spectrumLabel);
} }
try { try {
Utils.matToBitmap(mRgba, bmp); Utils.matToBitmap(mRgba, bmp);
} catch(Exception e) { } catch(Exception e) {
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle(); bmp.recycle();
bmp = null; bmp = null;
} }
return bmp; return bmp;
} }
private Scalar converScalarHsv2Rgba(Scalar hsvColor) private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
{
Mat pointMatRgba = new Mat(); Mat pointMatRgba = new Mat();
Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor); Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4); Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
return new Scalar(pointMatRgba.get(0, 0)); return new Scalar(pointMatRgba.get(0, 0));
} }
@Override @Override
public void run() { public void run() {
super.run(); super.run();

@ -11,66 +11,58 @@ import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar; import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc; import org.opencv.imgproc.Imgproc;
public class ColorBlobDetector public class ColorBlobDetector {
{ public void setColorRadius(Scalar radius) {
public void setColorRadius(Scalar radius) mColorRadius = radius;
{ }
mColorRadius = radius;
} public void setHsvColor(Scalar hsvColor) {
double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0;
public void setHsvColor(Scalar hsvColor) double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255;
{
double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0; mLowerBound.val[0] = minH;
double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255; mUpperBound.val[0] = maxH;
mLowerBound.val[0] = minH; mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1];
mUpperBound.val[0] = maxH; mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1];
mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1]; mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2];
mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1]; mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2];
mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2]; mLowerBound.val[3] = 0;
mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2]; mUpperBound.val[3] = 255;
mLowerBound.val[3] = 0; Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3);
mUpperBound.val[3] = 255;
for (int j = 0; j < maxH-minH; j++) {
Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3); byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255};
spectrumHsv.put(0, j, tmp);
for (int j = 0; j < maxH-minH; j++) }
{
byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4);
spectrumHsv.put(0, j, tmp); }
}
public Mat getSpectrum() {
Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); return mSpectrum;
}
}
public void setMinContourArea(double area) {
public Mat getSpectrum() mMinContourArea = area;
{ }
return mSpectrum;
} public void process(Mat rgbaImage) {
Mat pyrDownMat = new Mat();
public void setMinContourArea(double area)
{ Imgproc.pyrDown(rgbaImage, pyrDownMat);
mMinContourArea = area; Imgproc.pyrDown(pyrDownMat, pyrDownMat);
}
Mat hsvMat = new Mat();
public void process(Mat rgbaImage) Imgproc.cvtColor(pyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL);
{
Mat pyrDownMat = new Mat(); Mat Mask = new Mat();
Core.inRange(hsvMat, mLowerBound, mUpperBound, Mask);
Imgproc.pyrDown(rgbaImage, pyrDownMat); Mat dilatedMask = new Mat();
Imgproc.pyrDown(pyrDownMat, pyrDownMat); Imgproc.dilate(Mask, dilatedMask, new Mat());
Mat hsvMat = new Mat();
Imgproc.cvtColor(pyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL);
Mat Mask = new Mat();
Core.inRange(hsvMat, mLowerBound, mUpperBound, Mask);
Mat dilatedMask = new Mat();
Imgproc.dilate(Mask, dilatedMask, new Mat());
List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat(); Mat hierarchy = new Mat();
@ -80,40 +72,36 @@ public class ColorBlobDetector
// Find max contour area // Find max contour area
double maxArea = 0; double maxArea = 0;
Iterator<MatOfPoint> each = contours.iterator(); Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) while (each.hasNext()) {
{ MatOfPoint wrapper = each.next();
MatOfPoint wrapper = each.next(); double area = Imgproc.contourArea(wrapper);
double area = Imgproc.contourArea(wrapper); if (area > maxArea)
if (area > maxArea) maxArea = area;
maxArea = area;
} }
// Filter contours by area and resize to fit the original image size // Filter contours by area and resize to fit the original image size
mContours.clear(); mContours.clear();
each = contours.iterator(); each = contours.iterator();
while (each.hasNext()) while (each.hasNext()) {
{ MatOfPoint contour = each.next();
MatOfPoint contour = each.next(); if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) {
if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) Core.multiply(contour, new Scalar(4,4), contour);
{ mContours.add(contour);
Core.multiply(contour, new Scalar(4,4), contour); }
mContours.add(contour);
}
} }
} }
public List<MatOfPoint> getContours() public List<MatOfPoint> getContours() {
{ return mContours;
return mContours; }
}
// Lower and Upper bounds for range checking in HSV color space
// Lower and Upper bounds for range checking in HSV color space private Scalar mLowerBound = new Scalar(0);
private Scalar mLowerBound = new Scalar(0); private Scalar mUpperBound = new Scalar(0);
private Scalar mUpperBound = new Scalar(0); // Minimum contour area in percent for contours filtering
// Minimum contour area in percent for contours filtering private static double mMinContourArea = 0.1;
private static double mMinContourArea = 0.1; // Color radius for range checking in HSV color space
// Color radius for range checking in HSV color space private Scalar mColorRadius = new Scalar(25,50,50,0);
private Scalar mColorRadius = new Scalar(25,50,50,0); private Mat mSpectrum = new Mat();
private Mat mSpectrum = new Mat(); private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();
private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();
} }

@ -29,30 +29,29 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
synchronized (this) { synchronized (this) {
releaseCamera(); releaseCamera();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) { if (!mCamera.isOpened()) {
mCamera.release(); releaseCamera();
mCamera = null; Log.e(TAG, "Failed to open native camera");
Log.e(TAG, "Failed to open native camera"); return false;
return false; }
} }
}
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
} }
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera("+width+", "+height+")"); Log.i(TAG, "setupCamera("+width+", "+height+")");
synchronized (this) { synchronized (this) {
if (mCamera != null && mCamera.isOpened()) { if (mCamera != null && mCamera.isOpened()) {
List<Size> sizes = mCamera.getSupportedPreviewSizes(); List<Size> sizes = mCamera.getSupportedPreviewSizes();
@ -77,7 +76,7 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);
@ -111,12 +110,12 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
bmp = processFrame(mCamera); bmp = processFrame(mCamera);
} }
if (bmp != null) { if (bmp != null) {
Canvas canvas = mHolder.lockCanvas(); Canvas canvas = mHolder.lockCanvas();
if (canvas != null) { if (canvas != null) {
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null); canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas); mHolder.unlockCanvasAndPost(canvas);
} }
bmp.recycle(); bmp.recycle();

@ -9,7 +9,7 @@ include ../../sdk/native/jni/OpenCV.mk
LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH) LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := detection_based_tracker LOCAL_MODULE := detection_based_tracker

@ -22,26 +22,26 @@ class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
{ {
public: public:
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector): CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
IDetector(), IDetector(),
Detector(detector) Detector(detector)
{ {
LOGD("CascadeDetectorAdapter::Detect::Detect"); LOGD("CascadeDetectorAdapter::Detect::Detect");
CV_Assert(!detector.empty()); CV_Assert(!detector.empty());
} }
void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects) void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
{ {
LOGD("CascadeDetectorAdapter::Detect: begin"); LOGD("CascadeDetectorAdapter::Detect: begin");
LOGD("CascadeDetectorAdapter::Detect: scaleFactor=%.2f, minNeighbours=%d, minObjSize=(%dx%d), maxObjSize=(%dx%d)", scaleFactor, minNeighbours, minObjSize.width, minObjSize.height, maxObjSize.width, maxObjSize.height); LOGD("CascadeDetectorAdapter::Detect: scaleFactor=%.2f, minNeighbours=%d, minObjSize=(%dx%d), maxObjSize=(%dx%d)", scaleFactor, minNeighbours, minObjSize.width, minObjSize.height, maxObjSize.width, maxObjSize.height);
Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize); Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
LOGD("CascadeDetectorAdapter::Detect: end"); LOGD("CascadeDetectorAdapter::Detect: end");
} }
virtual ~CascadeDetectorAdapter() virtual ~CascadeDetectorAdapter()
{ {
LOGD("CascadeDetectorAdapter::Detect::~Detect"); LOGD("CascadeDetectorAdapter::Detect::~Detect");
} }
private: private:
CascadeDetectorAdapter(); CascadeDetectorAdapter();
cv::Ptr<cv::CascadeClassifier> Detector; cv::Ptr<cv::CascadeClassifier> Detector;
@ -51,17 +51,17 @@ struct DetectorAgregator
{ {
cv::Ptr<CascadeDetectorAdapter> mainDetector; cv::Ptr<CascadeDetectorAdapter> mainDetector;
cv::Ptr<CascadeDetectorAdapter> trackingDetector; cv::Ptr<CascadeDetectorAdapter> trackingDetector;
cv::Ptr<DetectionBasedTracker> tracker; cv::Ptr<DetectionBasedTracker> tracker;
DetectorAgregator(cv::Ptr<CascadeDetectorAdapter>& _mainDetector, cv::Ptr<CascadeDetectorAdapter>& _trackingDetector): DetectorAgregator(cv::Ptr<CascadeDetectorAdapter>& _mainDetector, cv::Ptr<CascadeDetectorAdapter>& _trackingDetector):
mainDetector(_mainDetector), mainDetector(_mainDetector),
trackingDetector(_trackingDetector) trackingDetector(_trackingDetector)
{ {
CV_Assert(!_mainDetector.empty()); CV_Assert(!_mainDetector.empty());
CV_Assert(!_trackingDetector.empty()); CV_Assert(!_trackingDetector.empty());
DetectionBasedTracker::Parameters DetectorParams; DetectionBasedTracker::Parameters DetectorParams;
tracker = new DetectionBasedTracker(mainDetector.ptr<DetectionBasedTracker::IDetector>(), trackingDetector.ptr<DetectionBasedTracker::IDetector>(), DetectorParams); tracker = new DetectionBasedTracker(mainDetector.ptr<DetectionBasedTracker::IDetector>(), trackingDetector.ptr<DetectionBasedTracker::IDetector>(), DetectorParams);
} }
}; };
@ -73,32 +73,32 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeC
jlong result = 0; jlong result = 0;
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject");
try try
{ {
cv::Ptr<CascadeDetectorAdapter> mainDetector = new CascadeDetectorAdapter(new CascadeClassifier(stdFileName)); cv::Ptr<CascadeDetectorAdapter> mainDetector = new CascadeDetectorAdapter(new CascadeClassifier(stdFileName));
cv::Ptr<CascadeDetectorAdapter> trackingDetector = new CascadeDetectorAdapter(new CascadeClassifier(stdFileName)); cv::Ptr<CascadeDetectorAdapter> trackingDetector = new CascadeDetectorAdapter(new CascadeClassifier(stdFileName));
result = (jlong)new DetectorAgregator(mainDetector, trackingDetector); result = (jlong)new DetectorAgregator(mainDetector, trackingDetector);
if (faceSize > 0) if (faceSize > 0)
{ {
mainDetector->setMinObjectSize(Size(faceSize, faceSize)); mainDetector->setMinObjectSize(Size(faceSize, faceSize));
//trackingDetector->setMinObjectSize(Size(faceSize, faceSize)); //trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
} }
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeCreateObject catched cv::Exception: %s", e.what()); LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeCreateObject catched unknown exception"); LOGD("nativeCreateObject catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject(...)}");
return 0; return 0;
} }
return result; return result;
@ -108,25 +108,25 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe
(JNIEnv * jenv, jclass, jlong thiz) (JNIEnv * jenv, jclass, jlong thiz)
{ {
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject");
try try
{ {
((DetectorAgregator*)thiz)->tracker->stop(); ((DetectorAgregator*)thiz)->tracker->stop();
delete (DetectorAgregator*)thiz; delete (DetectorAgregator*)thiz;
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeestroyObject catched cv::Exception: %s", e.what()); LOGD("nativeestroyObject catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeDestroyObject catched unknown exception"); LOGD("nativeDestroyObject catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject(...)}");
} }
} }
@ -134,24 +134,24 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt
(JNIEnv * jenv, jclass, jlong thiz) (JNIEnv * jenv, jclass, jlong thiz)
{ {
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart");
try try
{ {
((DetectorAgregator*)thiz)->tracker->run(); ((DetectorAgregator*)thiz)->tracker->run();
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeStart catched cv::Exception: %s", e.what()); LOGD("nativeStart catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeStart catched unknown exception"); LOGD("nativeStart catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart(...)}");
} }
} }
@ -159,24 +159,24 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt
(JNIEnv * jenv, jclass, jlong thiz) (JNIEnv * jenv, jclass, jlong thiz)
{ {
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop");
try try
{ {
((DetectorAgregator*)thiz)->tracker->stop(); ((DetectorAgregator*)thiz)->tracker->stop();
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeStop catched cv::Exception: %s", e.what()); LOGD("nativeStop catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeStop catched unknown exception"); LOGD("nativeStop catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop(...)}");
} }
} }
@ -184,28 +184,28 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSe
(JNIEnv * jenv, jclass, jlong thiz, jint faceSize) (JNIEnv * jenv, jclass, jlong thiz, jint faceSize)
{ {
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- BEGIN"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- BEGIN");
try try
{ {
if (faceSize > 0) if (faceSize > 0)
{ {
((DetectorAgregator*)thiz)->mainDetector->setMinObjectSize(Size(faceSize, faceSize)); ((DetectorAgregator*)thiz)->mainDetector->setMinObjectSize(Size(faceSize, faceSize));
//((DetectorAgregator*)thiz)->trackingDetector->setMinObjectSize(Size(faceSize, faceSize)); //((DetectorAgregator*)thiz)->trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
} }
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeStop catched cv::Exception: %s", e.what()); LOGD("nativeStop catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeSetFaceSize catched unknown exception"); LOGD("nativeSetFaceSize catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize(...)}");
} }
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- END"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- END");
} }
@ -215,27 +215,27 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces) (JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces)
{ {
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect");
try try
{ {
vector<Rect> RectFaces; vector<Rect> RectFaces;
((DetectorAgregator*)thiz)->tracker->process(*((Mat*)imageGray)); ((DetectorAgregator*)thiz)->tracker->process(*((Mat*)imageGray));
((DetectorAgregator*)thiz)->tracker->getObjects(RectFaces); ((DetectorAgregator*)thiz)->tracker->getObjects(RectFaces);
*((Mat*)faces) = Mat(RectFaces, true); *((Mat*)faces) = Mat(RectFaces, true);
} }
catch(cv::Exception e) catch(cv::Exception e)
{ {
LOGD("nativeCreateObject catched cv::Exception: %s", e.what()); LOGD("nativeCreateObject catched cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException"); jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je) if(!je)
je = jenv->FindClass("java/lang/Exception"); je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what()); jenv->ThrowNew(je, e.what());
} }
catch (...) catch (...)
{ {
LOGD("nativeDetect catched unknown exception"); LOGD("nativeDetect catched unknown exception");
jclass je = jenv->FindClass("java/lang/Exception"); jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect(...)}"); jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect(...)}");
} }
LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect END"); LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect END");
} }

@ -46,7 +46,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt
*/ */
JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize
(JNIEnv *, jclass, jlong, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: org_opencv_samples_fd_DetectionBasedTracker * Class: org_opencv_samples_fd_DetectionBasedTracker
* Method: nativeDetect * Method: nativeDetect

@ -4,49 +4,42 @@ import org.opencv.core.Mat;
import org.opencv.core.MatOfRect; import org.opencv.core.MatOfRect;
public class DetectionBasedTracker public class DetectionBasedTracker
{ {
public DetectionBasedTracker(String cascadeName, int minFaceSize) public DetectionBasedTracker(String cascadeName, int minFaceSize) {
{ mNativeObj = nativeCreateObject(cascadeName, minFaceSize);
mNativeObj = nativeCreateObject(cascadeName, minFaceSize); }
}
public void start() {
public void start() nativeStart(mNativeObj);
{ }
nativeStart(mNativeObj);
} public void stop() {
nativeStop(mNativeObj);
public void stop() }
{
nativeStop(mNativeObj); public void setMinFaceSize(int size) {
} nativeSetFaceSize(mNativeObj, size);
}
public void setMinFaceSize(int size)
{ public void detect(Mat imageGray, MatOfRect faces) {
nativeSetFaceSize(mNativeObj, size); nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr());
} }
public void detect(Mat imageGray, MatOfRect faces) public void release() {
{ nativeDestroyObject(mNativeObj);
nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr()); mNativeObj = 0;
} }
public void release() private long mNativeObj = 0;
{
nativeDestroyObject(mNativeObj); private static native long nativeCreateObject(String cascadeName, int minFaceSize);
mNativeObj = 0; private static native void nativeDestroyObject(long thiz);
} private static native void nativeStart(long thiz);
private static native void nativeStop(long thiz);
private long mNativeObj = 0; private static native void nativeSetFaceSize(long thiz, int size);
private static native void nativeDetect(long thiz, long inputImage, long faces);
private static native long nativeCreateObject(String cascadeName, int minFaceSize);
private static native void nativeDestroyObject(long thiz); static {
private static native void nativeStart(long thiz); System.loadLibrary("detection_based_tracker");
private static native void nativeStop(long thiz); }
private static native void nativeSetFaceSize(long thiz, int size);
private static native void nativeDetect(long thiz, long inputImage, long faces);
static
{
System.loadLibrary("detection_based_tracker");
}
} }

@ -12,74 +12,72 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class FdActivity extends Activity { public class FdActivity extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample-FD::Activity";
private MenuItem mItemFace50; private MenuItem mItemFace50;
private MenuItem mItemFace40; private MenuItem mItemFace40;
private MenuItem mItemFace30; private MenuItem mItemFace30;
private MenuItem mItemFace20; private MenuItem mItemFace20;
private MenuItem mItemType; private MenuItem mItemType;
private int mDetectorType = 0;
private FdView mView; private String[] mDetectorName;
private FdView mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
// Load native libs after OpenCV initialization
System.loadLibrary("detection_based_tracker");
// Create and set View private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
mView = new FdView(mAppContext); @Override
mView.setDetectorType(mDetectorType); public void onManagerConnected(int status) {
mView.setMinFaceSize(0.2f); switch (status) {
setContentView(mView); case LoaderCallbackInterface.SUCCESS:
// Check native OpenCV camera {
if( !mView.openCamera() ) { Log.i(TAG, "OpenCV loaded successfully");
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) {
mAppContext.finish();
}
});
MarketErrorMessage.show();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
// Load native libs after OpenCV initialization
System.loadLibrary("detection_based_tracker");
private int mDetectorType = 0; // Create and set View
private String[] mDetectorName; mView = new FdView(mAppContext);
mView.setDetectorType(mDetectorType);
mView.setMinFaceSize(0.2f);
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) {
mAppContext.finish();
}
});
MarketErrorMessage.show();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public FdActivity() { public FdActivity() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
@ -88,31 +86,25 @@ public class FdActivity extends Activity {
mDetectorName[FdView.NATIVE_DETECTOR] = "Native (tracking)"; mDetectorName[FdView.NATIVE_DETECTOR] = "Native (tracking)";
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (mView != null)
if (mView != null) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( mView != null && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
@ -120,12 +112,7 @@ public class FdActivity extends Activity {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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");
}
} }
@Override @Override
@ -136,7 +123,6 @@ public class FdActivity extends Activity {
mItemFace30 = menu.add("Face size 30%"); mItemFace30 = menu.add("Face size 30%");
mItemFace20 = menu.add("Face size 20%"); mItemFace20 = menu.add("Face size 20%");
mItemType = menu.add(mDetectorName[mDetectorType]); mItemType = menu.add(mDetectorName[mDetectorType]);
return true; return true;
} }
@ -146,16 +132,16 @@ public class FdActivity extends Activity {
if (item == mItemFace50) if (item == mItemFace50)
mView.setMinFaceSize(0.5f); mView.setMinFaceSize(0.5f);
else if (item == mItemFace40) else if (item == mItemFace40)
mView.setMinFaceSize(0.4f); mView.setMinFaceSize(0.4f);
else if (item == mItemFace30) else if (item == mItemFace30)
mView.setMinFaceSize(0.3f); mView.setMinFaceSize(0.3f);
else if (item == mItemFace20) else if (item == mItemFace20)
mView.setMinFaceSize(0.2f); mView.setMinFaceSize(0.2f);
else if (item == mItemType) else if (item == mItemType)
{ {
mDetectorType = (mDetectorType + 1) % mDetectorName.length; mDetectorType = (mDetectorType + 1) % mDetectorName.length;
item.setTitle(mDetectorName[mDetectorType]); item.setTitle(mDetectorName[mDetectorType]);
mView.setDetectorType(mDetectorType); mView.setDetectorType(mDetectorType);
} }
return true; return true;
} }

@ -22,7 +22,7 @@ import android.util.Log;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
class FdView extends SampleCvViewBase { class FdView extends SampleCvViewBase {
private static final String TAG = "Sample::FdView"; private static final String TAG = "Sample-FD::View";
private Mat mRgba; private Mat mRgba;
private Mat mGray; private Mat mGray;
private File mCascadeFile; private File mCascadeFile;
@ -30,38 +30,32 @@ class FdView extends SampleCvViewBase {
private DetectionBasedTracker mNativeDetector; private DetectionBasedTracker mNativeDetector;
private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255); private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255);
public static final int JAVA_DETECTOR = 0; public static final int JAVA_DETECTOR = 0;
public static final int NATIVE_DETECTOR = 1; public static final int NATIVE_DETECTOR = 1;
private int mDetectorType = JAVA_DETECTOR; private int mDetectorType = JAVA_DETECTOR;
private float mRelativeFaceSize = 0; private float mRelativeFaceSize = 0;
private int mAbsoluteFaceSize = 0; private int mAbsoluteFaceSize = 0;
public void setMinFaceSize(float faceSize) public void setMinFaceSize(float faceSize) {
{ mRelativeFaceSize = faceSize;
mRelativeFaceSize = faceSize; mAbsoluteFaceSize = 0;
mAbsoluteFaceSize = 0;
} }
public void setDetectorType(int type) public void setDetectorType(int type) {
{ if (mDetectorType != type) {
if (mDetectorType != type) mDetectorType = type;
{
mDetectorType = type; if (type == NATIVE_DETECTOR) {
Log.i(TAG, "Detection Based Tracker enabled");
if (type == NATIVE_DETECTOR) mNativeDetector.start();
{ } else {
Log.i(TAG, "Detection Based Tracker enabled"); Log.i(TAG, "Cascade detector enabled");
mNativeDetector.start(); mNativeDetector.stop();
} }
else }
{
Log.i(TAG, "Cascade detector enabled");
mNativeDetector.stop();
}
}
} }
public FdView(Context context) { public FdView(Context context) {
@ -89,7 +83,7 @@ class FdView extends SampleCvViewBase {
Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath()); Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());
mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0); mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
cascadeDir.delete(); cascadeDir.delete();
} catch (IOException e) { } catch (IOException e) {
@ -99,7 +93,7 @@ class FdView extends SampleCvViewBase {
} }
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) { synchronized (this) {
// initialize Mats before usage // initialize Mats before usage
mGray = new Mat(); mGray = new Mat();
@ -107,41 +101,36 @@ class FdView extends SampleCvViewBase {
} }
super.surfaceCreated(holder); super.surfaceCreated(holder);
} }
@Override @Override
protected Bitmap processFrame(VideoCapture capture) { protected Bitmap processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME); capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
if (mAbsoluteFaceSize == 0) if (mAbsoluteFaceSize == 0) {
{ int height = mGray.rows();
int height = mGray.rows(); if (Math.round(height * mRelativeFaceSize) > 0) {
if (Math.round(height * mRelativeFaceSize) > 0); mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
{ }
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize); mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
}
mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
} }
MatOfRect faces = new MatOfRect(); MatOfRect faces = new MatOfRect();
if (mDetectorType == JAVA_DETECTOR) if (mDetectorType == JAVA_DETECTOR) {
{ if (mJavaDetector != null)
if (mJavaDetector != null) mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2 // TODO: objdetect.CV_HAAR_SCALE_IMAGE new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
, new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
} }
else if (mDetectorType == NATIVE_DETECTOR) else if (mDetectorType == NATIVE_DETECTOR) {
{ if (mNativeDetector != null)
if (mNativeDetector != null) mNativeDetector.detect(mGray, faces);
mNativeDetector.detect(mGray, faces);
} }
else else {
{ Log.e(TAG, "Detection method is not selected!");
Log.e(TAG, "Detection method is not selected!");
} }
Rect[] facesArray = faces.toArray(); Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++) for (int i = 0; i < facesArray.length; i++)
Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
@ -149,13 +138,13 @@ class FdView extends SampleCvViewBase {
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
try { try {
Utils.matToBitmap(mRgba, bmp); Utils.matToBitmap(mRgba, bmp);
} catch(Exception e) { } catch(Exception e) {
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle(); bmp.recycle();
bmp = null; bmp = null;
} }
return bmp; return bmp;
} }
@ -170,9 +159,9 @@ class FdView extends SampleCvViewBase {
if (mGray != null) if (mGray != null)
mGray.release(); mGray.release();
if (mCascadeFile != null) if (mCascadeFile != null)
mCascadeFile.delete(); mCascadeFile.delete();
if (mNativeDetector != null) if (mNativeDetector != null)
mNativeDetector.release(); mNativeDetector.release();
mRgba = null; mRgba = null;
mGray = null; mGray = null;

@ -31,28 +31,27 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
synchronized (this) { synchronized (this) {
releaseCamera(); releaseCamera();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) { if (!mCamera.isOpened()) {
mCamera.release(); releaseCamera();
mCamera = null; Log.e(TAG, "Failed to open native camera");
Log.e(TAG, "Failed to open native camera"); return false;
return false; }
} }
}
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
} }
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera("+width+", "+height+")"); Log.i(TAG, "setupCamera("+width+", "+height+")");
synchronized (this) { synchronized (this) {
@ -79,7 +78,7 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -12,10 +12,11 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class ImageManipulationsActivity extends Activity { public class ImageManipulationsActivity extends Activity {
private static final String TAG = "Sample-ImageManipulations::Activity"; private static final String TAG = "Sample-ImageManipulations::Activity";
public static final int VIEW_MODE_RGBA = 0; public static final int VIEW_MODE_RGBA = 0;
public static final int VIEW_MODE_HIST = 1; public static final int VIEW_MODE_HIST = 1;
@ -36,85 +37,79 @@ public class ImageManipulationsActivity extends Activity {
private MenuItem mItemPreviewPosterize; private MenuItem mItemPreviewPosterize;
public static int viewMode = VIEW_MODE_RGBA; public static int viewMode = VIEW_MODE_RGBA;
private ImageManipulationsView mView; private ImageManipulationsView mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Create and set View // Create and set View
mView = new ImageManipulationsView(mAppContext); mView = new ImageManipulationsView(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public ImageManipulationsActivity() { public ImageManipulationsActivity() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( (null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
@ -122,12 +117,7 @@ public class ImageManipulationsActivity extends Activity {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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");
}
} }
@Override @Override

@ -24,7 +24,7 @@ class ImageManipulationsView extends SampleCvViewBase {
private Size mSize0; private Size mSize0;
private Size mSizeRgba; private Size mSizeRgba;
private Size mSizeRgbaInner; private Size mSizeRgbaInner;
private Mat mRgba; private Mat mRgba;
private Mat mGray; private Mat mGray;
private Mat mIntermediateMat; private Mat mIntermediateMat;
@ -55,7 +55,7 @@ class ImageManipulationsView extends SampleCvViewBase {
} }
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) { synchronized (this) {
// initialize Mats before usage // initialize Mats before usage
mGray = new Mat(); mGray = new Mat();
@ -71,11 +71,11 @@ class ImageManipulationsView extends SampleCvViewBase {
mMat0 = new Mat(); mMat0 = new Mat();
mColorsRGB = new Scalar[] { new Scalar(200, 0, 0, 255), new Scalar(0, 200, 0, 255), new Scalar(0, 0, 200, 255) }; mColorsRGB = new Scalar[] { new Scalar(200, 0, 0, 255), new Scalar(0, 200, 0, 255), new Scalar(0, 0, 200, 255) };
mColorsHue = new Scalar[] { mColorsHue = new Scalar[] {
new Scalar(255, 0, 0, 255), new Scalar(255, 60, 0, 255), new Scalar(255, 120, 0, 255), new Scalar(255, 180, 0, 255), new Scalar(255, 240, 0, 255), new Scalar(255, 0, 0, 255), new Scalar(255, 60, 0, 255), new Scalar(255, 120, 0, 255), new Scalar(255, 180, 0, 255), new Scalar(255, 240, 0, 255),
new Scalar(215, 213, 0, 255), new Scalar(150, 255, 0, 255), new Scalar(85, 255, 0, 255), new Scalar(20, 255, 0, 255), new Scalar(0, 255, 30, 255), new Scalar(215, 213, 0, 255), new Scalar(150, 255, 0, 255), new Scalar(85, 255, 0, 255), new Scalar(20, 255, 0, 255), new Scalar(0, 255, 30, 255),
new Scalar(0, 255, 85, 255), new Scalar(0, 255, 150, 255), new Scalar(0, 255, 215, 255), new Scalar(0, 234, 255, 255), new Scalar(0, 170, 255, 255), new Scalar(0, 255, 85, 255), new Scalar(0, 255, 150, 255), new Scalar(0, 255, 215, 255), new Scalar(0, 234, 255, 255), new Scalar(0, 170, 255, 255),
new Scalar(0, 120, 255, 255), new Scalar(0, 60, 255, 255), new Scalar(0, 0, 255, 255), new Scalar(64, 0, 255, 255), new Scalar(120, 0, 255, 255), new Scalar(0, 120, 255, 255), new Scalar(0, 60, 255, 255), new Scalar(0, 0, 255, 255), new Scalar(64, 0, 255, 255), new Scalar(120, 0, 255, 255),
new Scalar(180, 0, 255, 255), new Scalar(255, 0, 255, 255), new Scalar(255, 0, 215, 255), new Scalar(255, 0, 85, 255), new Scalar(255, 0, 0, 255) new Scalar(180, 0, 255, 255), new Scalar(255, 0, 255, 255), new Scalar(255, 0, 215, 255), new Scalar(255, 0, 85, 255), new Scalar(255, 0, 0, 255)
}; };
mWhilte = Scalar.all(255); mWhilte = Scalar.all(255);
mP1 = new Point(); mP1 = new Point();
@ -83,13 +83,13 @@ class ImageManipulationsView extends SampleCvViewBase {
} }
super.surfaceCreated(holder); super.surfaceCreated(holder);
} }
private void CreateAuxiliaryMats() { private void CreateAuxiliaryMats() {
if (mRgba.empty()) if (mRgba.empty())
return; return;
mSizeRgba = mRgba.size(); mSizeRgba = mRgba.size();
int rows = (int) mSizeRgba.height; int rows = (int) mSizeRgba.height;
int cols = (int) mSizeRgba.width; int cols = (int) mSizeRgba.width;
@ -102,7 +102,7 @@ class ImageManipulationsView extends SampleCvViewBase {
if (mRgbaInnerWindow == null) if (mRgbaInnerWindow == null)
mRgbaInnerWindow = mRgba.submat(top, top + height, left, left + width); mRgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
mSizeRgbaInner = mRgbaInnerWindow.size(); mSizeRgbaInner = mRgbaInnerWindow.size();
if (mGrayInnerWindow == null && !mGray.empty()) if (mGrayInnerWindow == null && !mGray.empty())
mGrayInnerWindow = mGray.submat(top, top + height, left, left + width); mGrayInnerWindow = mGray.submat(top, top + height, left, left + width);
@ -134,38 +134,38 @@ class ImageManipulationsView extends SampleCvViewBase {
int offset = (int) ((mSizeRgba.width - (5*mHistSizeNum + 4*10)*thikness)/2); int offset = (int) ((mSizeRgba.width - (5*mHistSizeNum + 4*10)*thikness)/2);
// RGB // RGB
for(int c=0; c<3; c++) { for(int c=0; c<3; c++) {
Imgproc.calcHist(Arrays.asList(mRgba), mChannels[c], mMat0, mHist, mHistSize, mRanges); Imgproc.calcHist(Arrays.asList(mRgba), mChannels[c], mMat0, mHist, mHistSize, mRanges);
Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF); Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF);
mHist.get(0, 0, mBuff); mHist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) { for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness; mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
mP1.y = mSizeRgba.height-1; mP1.y = mSizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h]; mP2.y = mP1.y - 2 - (int)mBuff[h];
Core.line(mRgba, mP1, mP2, mColorsRGB[c], thikness); Core.line(mRgba, mP1, mP2, mColorsRGB[c], thikness);
} }
} }
// Value and Hue // Value and Hue
Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_RGB2HSV_FULL); Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_RGB2HSV_FULL);
// Value // Value
Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[2], mMat0, mHist, mHistSize, mRanges); Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[2], mMat0, mHist, mHistSize, mRanges);
Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF); Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF);
mHist.get(0, 0, mBuff); mHist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) { for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (3 * (mHistSizeNum + 10) + h) * thikness; mP1.x = mP2.x = offset + (3 * (mHistSizeNum + 10) + h) * thikness;
mP1.y = mSizeRgba.height-1; mP1.y = mSizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h]; mP2.y = mP1.y - 2 - (int)mBuff[h];
Core.line(mRgba, mP1, mP2, mWhilte, thikness); Core.line(mRgba, mP1, mP2, mWhilte, thikness);
} }
// Hue // Hue
Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[0], mMat0, mHist, mHistSize, mRanges); Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[0], mMat0, mHist, mHistSize, mRanges);
Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF); Core.normalize(mHist, mHist, mSizeRgba.height/2, 0, Core.NORM_INF);
mHist.get(0, 0, mBuff); mHist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) { for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (4 * (mHistSizeNum + 10) + h) * thikness; mP1.x = mP2.x = offset + (4 * (mHistSizeNum + 10) + h) * thikness;
mP1.y = mSizeRgba.height-1; mP1.y = mSizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h]; mP2.y = mP1.y - 2 - (int)mBuff[h];
Core.line(mRgba, mP1, mP2, mColorsHue[h], thikness); Core.line(mRgba, mP1, mP2, mColorsHue[h], thikness);
} }
break; break;
case ImageManipulationsActivity.VIEW_MODE_CANNY: case ImageManipulationsActivity.VIEW_MODE_CANNY:
@ -231,10 +231,10 @@ class ImageManipulationsView extends SampleCvViewBase {
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
try { try {
Utils.matToBitmap(mRgba, bmp); Utils.matToBitmap(mRgba, bmp);
return bmp; return bmp;
} catch(Exception e) { } catch(Exception e) {
Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage()); Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle(); bmp.recycle();
return null; return null;
} }

@ -31,28 +31,27 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
synchronized (this) { synchronized (this) {
releaseCamera(); releaseCamera();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) { if (!mCamera.isOpened()) {
mCamera.release(); releaseCamera();
mCamera = null; Log.e(TAG, "Failed to open native camera");
Log.e(TAG, "Failed to open native camera"); return false;
return false; }
} }
}
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
} }
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera("+width+", "+height+")"); Log.i(TAG, "setupCamera("+width+", "+height+")");
synchronized (this) { synchronized (this) {
@ -79,7 +78,7 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -10,8 +10,8 @@ import android.view.MenuItem;
import android.view.Window; import android.view.Window;
public class Sample0Base extends Activity { public class Sample0Base extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
private MenuItem mItemPreviewRGBA; private MenuItem mItemPreviewRGBA;
private MenuItem mItemPreviewGray; private MenuItem mItemPreviewGray;
@ -22,31 +22,31 @@ public class Sample0Base extends Activity {
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); super.onPause();
mView.releaseCamera(); mView.releaseCamera();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} }
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
@ -68,9 +68,9 @@ public class Sample0Base extends Activity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "Menu Item selected " + item); Log.i(TAG, "Menu Item selected " + item);
if (item == mItemPreviewRGBA) if (item == mItemPreviewRGBA)
mView.setViewMode(Sample0View.VIEW_MODE_RGBA); mView.setViewMode(Sample0View.VIEW_MODE_RGBA);
else if (item == mItemPreviewGray) else if (item == mItemPreviewGray)
mView.setViewMode(Sample0View.VIEW_MODE_GRAY); mView.setViewMode(Sample0View.VIEW_MODE_GRAY);
return true; return true;
} }
} }

@ -5,17 +5,17 @@ import android.graphics.Bitmap;
import android.util.Log; import android.util.Log;
class Sample0View extends SampleViewBase { class Sample0View extends SampleViewBase {
private static final String TAG = "Sample0View"; private static final String TAG = "Sample0View";
int mSize; int mSize;
int[] mRGBA; int[] mRGBA;
private Bitmap mBitmap; private Bitmap mBitmap;
private int mViewMode; private int mViewMode;
public static final int VIEW_MODE_RGBA = 0; public static final int VIEW_MODE_RGBA = 0;
public static final int VIEW_MODE_GRAY = 1; public static final int VIEW_MODE_GRAY = 1;
public Sample0View(Context context) { public Sample0View(Context context) {
super(context); super(context);
mSize = 0; mSize = 0;
@ -25,7 +25,7 @@ class Sample0View extends SampleViewBase {
@Override @Override
protected Bitmap processFrame(byte[] data) { protected Bitmap processFrame(byte[] data) {
int frameSize = getFrameWidth() * getFrameHeight(); int frameSize = getFrameWidth() * getFrameHeight();
int[] rgba = mRGBA; int[] rgba = mRGBA;
final int view_mode = mViewMode; final int view_mode = mViewMode;
@ -35,15 +35,15 @@ class Sample0View extends SampleViewBase {
rgba[i] = 0xff000000 + (y << 16) + (y << 8) + y; rgba[i] = 0xff000000 + (y << 16) + (y << 8) + y;
} }
} else if (view_mode == VIEW_MODE_RGBA) { } else if (view_mode == VIEW_MODE_RGBA) {
for (int i = 0; i < getFrameHeight(); i++) for (int i = 0; i < getFrameHeight(); i++) {
for (int j = 0; j < getFrameWidth(); j++) { for (int j = 0; j < getFrameWidth(); j++) {
int index = i * getFrameWidth() + j; int index = i * getFrameWidth() + j;
int supply_index = frameSize + (i >> 1) * getFrameWidth() + (j & ~1); int supply_index = frameSize + (i >> 1) * getFrameWidth() + (j & ~1);
int y = (0xff & ((int) data[index])); int y = (0xff & ((int) data[index]));
int u = (0xff & ((int) data[supply_index + 0])); int u = (0xff & ((int) data[supply_index + 0]));
int v = (0xff & ((int) data[supply_index + 1])); int v = (0xff & ((int) data[supply_index + 1]));
y = y < 16 ? 16 : y; y = y < 16 ? 16 : y;
float y_conv = 1.164f * (y - 16); float y_conv = 1.164f * (y - 16);
int r = Math.round(y_conv + 1.596f * (v - 128)); int r = Math.round(y_conv + 1.596f * (v - 128));
int g = Math.round(y_conv - 0.813f * (v - 128) - 0.391f * (u - 128)); int g = Math.round(y_conv - 0.813f * (v - 128) - 0.391f * (u - 128));
@ -55,35 +55,36 @@ class Sample0View extends SampleViewBase {
rgba[i * getFrameWidth() + j] = 0xff000000 + (b << 16) + (g << 8) + r; rgba[i * getFrameWidth() + j] = 0xff000000 + (b << 16) + (g << 8) + r;
} }
}
} }
mBitmap.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight()); mBitmap.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight());
return mBitmap; return mBitmap;
} }
@Override @Override
protected void onPreviewStarted(int previewWidth, int previewHeight) { protected void onPreviewStarted(int previewWidth, int previewHeight) {
Log.i(TAG, "onPreviewStarted("+previewWidth+", "+previewHeight+")"); Log.i(TAG, "onPreviewStarted("+previewWidth+", "+previewHeight+")");
/* Create a bitmap that will be used through to calculate the image to */ /* Create a bitmap that will be used through to calculate the image to */
mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888); mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
mRGBA = new int[previewWidth * previewHeight]; mRGBA = new int[previewWidth * previewHeight];
} }
@Override @Override
protected void onPreviewStopped() { protected void onPreviewStopped() {
Log.i(TAG, "onPreviewStopped"); Log.i(TAG, "onPreviewStopped");
if(mBitmap != null) { if(mBitmap != null) {
mBitmap.recycle(); mBitmap.recycle();
mBitmap = null; mBitmap = null;
} }
if(mRGBA != null) { if(mRGBA != null) {
mRGBA = null; mRGBA = null;
} }
} }
public void setViewMode(int viewMode) { public void setViewMode(int viewMode) {
Log.i(TAG, "setViewMode("+viewMode+")"); Log.i(TAG, "setViewMode("+viewMode+")");
mViewMode = viewMode; mViewMode = viewMode;
} }
} }

@ -46,7 +46,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
mCamera.setPreviewTexture( new SurfaceTexture(10) ); mCamera.setPreviewTexture( new SurfaceTexture(10) );
else else
mCamera.setPreviewDisplay(null); mCamera.setPreviewDisplay(null);
} }
@ -55,27 +55,27 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
releaseCamera(); releaseCamera();
mCamera = Camera.open(); mCamera = Camera.open();
if(mCamera == null) { if(mCamera == null) {
Log.e(TAG, "Can't open camera!"); Log.e(TAG, "Can't open camera!");
return false; return false;
} }
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() { mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) { synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length); System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify(); SampleViewBase.this.notify();
} }
camera.addCallbackBuffer(mBuffer); camera.addCallbackBuffer(mBuffer);
} }
}); });
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
mThreadRun = false; mThreadRun = false;
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.stopPreview(); mCamera.stopPreview();
mCamera.setPreviewCallback(null); mCamera.setPreviewCallback(null);
mCamera.release(); mCamera.release();
@ -84,7 +84,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
onPreviewStopped(); onPreviewStopped();
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera"); Log.i(TAG, "setupCamera");
synchronized (this) { synchronized (this) {
@ -107,15 +107,15 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
params.setPreviewSize(getFrameWidth(), getFrameHeight()); params.setPreviewSize(getFrameWidth(), getFrameHeight());
List<String> FocusModes = params.getSupportedFocusModes(); List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{ {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} }
mCamera.setParameters(params); mCamera.setParameters(params);
/* Now allocate the buffer */ /* Now allocate the buffer */
params = mCamera.getParameters(); params = mCamera.getParameters();
int size = params.getPreviewSize().width * params.getPreviewSize().height; int size = params.getPreviewSize().width * params.getPreviewSize().height;
@ -125,11 +125,11 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
mFrame = new byte [size]; mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer); mCamera.addCallbackBuffer(mBuffer);
try { try {
setPreview(); setPreview();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
} }
/* Notify that the preview is about to be started and deliver preview size */ /* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height); onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);
@ -139,7 +139,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -12,6 +12,7 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class Sample1Java extends Activity { public class Sample1Java extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
@ -22,81 +23,76 @@ public class Sample1Java extends Activity {
private Sample1View mView; private Sample1View mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Create and set View // Create and set View
mView = new Sample1View(mAppContext); mView = new Sample1View(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: /** 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(); Log.d(TAG, "Google Play service is not accessible!");
MarketErrorMessage.setTitle("OpenCV Manager"); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
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.setTitle("OpenCV Manager");
MarketErrorMessage.setCancelable(false); // This blocks the 'BACK' button 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.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setCancelable(false); // This blocks the 'BACK' button
public void onClick(DialogInterface dialog, int which) { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
mAppContext.finish(); public void onClick(DialogInterface dialog, int which) {
} mAppContext.finish();
}); }
MarketErrorMessage.show(); });
} break; MarketErrorMessage.show();
default: } break;
{ default:
super.onManagerConnected(status); {
} break; super.onManagerConnected(status);
} } break;
} }
}; }
};
public Sample1Java() { public Sample1Java() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if( (null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
@ -104,12 +100,7 @@ public class Sample1Java extends Activity {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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");
}
} }
@Override @Override
@ -125,11 +116,11 @@ public class Sample1Java extends Activity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "Menu Item selected " + item); Log.i(TAG, "Menu Item selected " + item);
if (item == mItemPreviewRGBA) { if (item == mItemPreviewRGBA) {
mView.setViewMode(Sample1View.VIEW_MODE_RGBA); mView.setViewMode(Sample1View.VIEW_MODE_RGBA);
} else if (item == mItemPreviewGray) { } else if (item == mItemPreviewGray) {
mView.setViewMode(Sample1View.VIEW_MODE_GRAY); mView.setViewMode(Sample1View.VIEW_MODE_GRAY);
} else if (item == mItemPreviewCanny) { } else if (item == mItemPreviewCanny) {
mView.setViewMode(Sample1View.VIEW_MODE_CANNY); mView.setViewMode(Sample1View.VIEW_MODE_CANNY);
} }
return true; return true;
} }

@ -22,35 +22,35 @@ class Sample1View extends SampleViewBase {
private Mat mRgba; private Mat mRgba;
private Mat mGraySubmat; private Mat mGraySubmat;
private Mat mIntermediateMat; private Mat mIntermediateMat;
private Bitmap mBitmap; private Bitmap mBitmap;
private int mViewMode; private int mViewMode;
public Sample1View(Context context) { public Sample1View(Context context) {
super(context); super(context);
mViewMode = VIEW_MODE_RGBA; mViewMode = VIEW_MODE_RGBA;
} }
@Override @Override
protected void onPreviewStarted(int previewWidth, int previewHeight) { protected void onPreviewStarted(int previewWidth, int previewHeight) {
synchronized (this) { synchronized (this) {
// initialize Mats before usage // initialize Mats before usage
mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1); mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth()); mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth());
mRgba = new Mat(); mRgba = new Mat();
mIntermediateMat = new Mat(); mIntermediateMat = new Mat();
mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888); mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
} }
} }
@Override @Override
protected void onPreviewStopped() { protected void onPreviewStopped() {
if(mBitmap != null) { if(mBitmap != null) {
mBitmap.recycle(); mBitmap.recycle();
} }
synchronized (this) { synchronized (this) {
// Explicitly deallocate Mats // Explicitly deallocate Mats
if (mYuv != null) if (mYuv != null)
mYuv.release(); mYuv.release();
@ -101,7 +101,7 @@ class Sample1View extends SampleViewBase {
} }
public void setViewMode(int viewMode) { public void setViewMode(int viewMode) {
mViewMode = viewMode; mViewMode = viewMode;
} }
} }

@ -46,35 +46,35 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
mCamera.setPreviewTexture( new SurfaceTexture(10) ); mCamera.setPreviewTexture( new SurfaceTexture(10) );
else else
mCamera.setPreviewDisplay(null); mCamera.setPreviewDisplay(null);
} }
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
releaseCamera(); releaseCamera();
mCamera = Camera.open(); mCamera = Camera.open();
if(mCamera == null) { if(mCamera == null) {
Log.e(TAG, "Can't open camera!"); Log.e(TAG, "Can't open camera!");
return false; return false;
} }
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() { mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) { synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length); System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify(); SampleViewBase.this.notify();
} }
camera.addCallbackBuffer(mBuffer); camera.addCallbackBuffer(mBuffer);
} }
}); });
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
mThreadRun = false; mThreadRun = false;
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.stopPreview(); mCamera.stopPreview();
mCamera.setPreviewCallback(null); mCamera.setPreviewCallback(null);
mCamera.release(); mCamera.release();
@ -83,7 +83,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
onPreviewStopped(); onPreviewStopped();
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera"); Log.i(TAG, "setupCamera");
synchronized (this) { synchronized (this) {
@ -106,15 +106,15 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
params.setPreviewSize(getFrameWidth(), getFrameHeight()); params.setPreviewSize(getFrameWidth(), getFrameHeight());
List<String> FocusModes = params.getSupportedFocusModes(); List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{ {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} }
mCamera.setParameters(params); mCamera.setParameters(params);
/* Now allocate the buffer */ /* Now allocate the buffer */
params = mCamera.getParameters(); params = mCamera.getParameters();
int size = params.getPreviewSize().width * params.getPreviewSize().height; int size = params.getPreviewSize().width * params.getPreviewSize().height;
@ -124,11 +124,11 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
mFrame = new byte [size]; mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer); mCamera.addCallbackBuffer(mBuffer);
try { try {
setPreview(); setPreview();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
} }
/* Notify that the preview is about to be started and deliver preview size */ /* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height); onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);
@ -138,7 +138,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -12,6 +12,7 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class Sample2NativeCamera extends Activity { public class Sample2NativeCamera extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
@ -25,85 +26,79 @@ public class Sample2NativeCamera extends Activity {
private MenuItem mItemPreviewCanny; private MenuItem mItemPreviewCanny;
public static int viewMode = VIEW_MODE_RGBA; public static int viewMode = VIEW_MODE_RGBA;
private Sample2View mView; private Sample2View mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Create and set View // Create and set View
mView = new Sample2View(mAppContext); mView = new Sample2View(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public Sample2NativeCamera() { public Sample2NativeCamera() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if((null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
@ -111,11 +106,7 @@ public class Sample2NativeCamera extends Activity {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
Log.i(TAG, "Trying to load OpenCV library"); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
{
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
} }
@Override @Override

@ -31,7 +31,7 @@ class Sample2View extends SampleCvViewBase {
mRgba = new Mat(); mRgba = new Mat();
mIntermediateMat = new Mat(); mIntermediateMat = new Mat();
} }
super.surfaceCreated(holder); super.surfaceCreated(holder);
} }
@ -50,16 +50,16 @@ class Sample2View extends SampleCvViewBase {
capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME); capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
Imgproc.Canny(mGray, mIntermediateMat, 80, 100); Imgproc.Canny(mGray, mIntermediateMat, 80, 100);
Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4); Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
break; break;
} }
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
try { try {
Utils.matToBitmap(mRgba, bmp); Utils.matToBitmap(mRgba, bmp);
return bmp; return bmp;
} catch(Exception e) { } catch(Exception e) {
Log.e("org.opencv.samples.tutorial2", "Utils.matToBitmap() throws an exception: " + e.getMessage()); Log.e("org.opencv.samples.tutorial2", "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle(); bmp.recycle();
return null; return null;
} }

@ -29,28 +29,27 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
synchronized (this) { synchronized (this) {
releaseCamera(); releaseCamera();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) { if (!mCamera.isOpened()) {
mCamera.release(); releaseCamera();
mCamera = null; Log.e(TAG, "Failed to open native camera");
Log.e(TAG, "Failed to open native camera"); return false;
return false; }
} }
}
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
mCamera = null; mCamera = null;
} }
} }
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera("+width+", "+height+")"); Log.i(TAG, "setupCamera("+width+", "+height+")");
synchronized (this) { synchronized (this) {
@ -77,7 +76,7 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);
@ -115,8 +114,8 @@ public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHol
if (bmp != null) { if (bmp != null) {
Canvas canvas = mHolder.lockCanvas(); Canvas canvas = mHolder.lockCanvas();
if (canvas != null) { if (canvas != null) {
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
canvas.drawBitmap(bmp, (canvas.getWidth()-bmp.getWidth()) / 2, (canvas.getHeight()-bmp.getHeight()) / 2, null); canvas.drawBitmap(bmp, (canvas.getWidth()-bmp.getWidth()) / 2, (canvas.getHeight()-bmp.getHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas); mHolder.unlockCanvasAndPost(canvas);
} }
bmp.recycle(); bmp.recycle();

@ -10,91 +10,86 @@ import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class Sample3Native extends Activity { public class Sample3Native extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
private Sample3View mView; private Sample3View mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Load native library after(!) OpenCV initialization // Load native library after(!) OpenCV initialization
System.loadLibrary("native_sample"); System.loadLibrary("native_sample");
// Create and set View // Create and set View
mView = new Sample3View(mAppContext); mView = new Sample3View(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public Sample3Native() { public Sample3Native() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if((null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
@ -102,10 +97,6 @@ public class Sample3Native extends Activity {
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
{
Log.e(TAG, "Cannot connect to OpenCV Manager");
}
} }
} }

@ -4,30 +4,30 @@ import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
class Sample3View extends SampleViewBase { class Sample3View extends SampleViewBase {
private int mFrameSize; private int mFrameSize;
private Bitmap mBitmap; private Bitmap mBitmap;
private int[] mRGBA; private int[] mRGBA;
public Sample3View(Context context) { public Sample3View(Context context) {
super(context); super(context);
} }
@Override @Override
protected void onPreviewStarted(int previewWidtd, int previewHeight) { protected void onPreviewStarted(int previewWidtd, int previewHeight) {
mFrameSize = previewWidtd * previewHeight; mFrameSize = previewWidtd * previewHeight;
mRGBA = new int[mFrameSize]; mRGBA = new int[mFrameSize];
mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888); mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888);
} }
@Override @Override
protected void onPreviewStopped() { protected void onPreviewStopped() {
if(mBitmap != null) { if(mBitmap != null) {
mBitmap.recycle(); mBitmap.recycle();
mBitmap = null; mBitmap = null;
} }
mRGBA = null; mRGBA = null;
} }
@Override @Override
protected Bitmap processFrame(byte[] data) { protected Bitmap processFrame(byte[] data) {
@ -35,7 +35,7 @@ class Sample3View extends SampleViewBase {
FindFeatures(getFrameWidth(), getFrameHeight(), data, rgba); FindFeatures(getFrameWidth(), getFrameHeight(), data, rgba);
Bitmap bmp = mBitmap; Bitmap bmp = mBitmap;
bmp.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight()); bmp.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight());
return bmp; return bmp;
} }

@ -45,35 +45,35 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
mCamera.setPreviewTexture( new SurfaceTexture(10) ); mCamera.setPreviewTexture( new SurfaceTexture(10) );
else else
mCamera.setPreviewDisplay(null); mCamera.setPreviewDisplay(null);
} }
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
releaseCamera(); releaseCamera();
mCamera = Camera.open(); mCamera = Camera.open();
if(mCamera == null) { if(mCamera == null) {
Log.e(TAG, "Can't open camera!"); Log.e(TAG, "Can't open camera!");
return false; return false;
} }
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() { mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) { synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length); System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify(); SampleViewBase.this.notify();
} }
camera.addCallbackBuffer(mBuffer); camera.addCallbackBuffer(mBuffer);
} }
}); });
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
mThreadRun = false; mThreadRun = false;
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.stopPreview(); mCamera.stopPreview();
mCamera.setPreviewCallback(null); mCamera.setPreviewCallback(null);
mCamera.release(); mCamera.release();
@ -82,7 +82,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
onPreviewStopped(); onPreviewStopped();
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera"); Log.i(TAG, "setupCamera");
synchronized (this) { synchronized (this) {
@ -105,15 +105,15 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
params.setPreviewSize(getFrameWidth(), getFrameHeight()); params.setPreviewSize(getFrameWidth(), getFrameHeight());
List<String> FocusModes = params.getSupportedFocusModes(); List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{ {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} }
mCamera.setParameters(params); mCamera.setParameters(params);
/* Now allocate the buffer */ /* Now allocate the buffer */
params = mCamera.getParameters(); params = mCamera.getParameters();
int size = params.getPreviewSize().width * params.getPreviewSize().height; int size = params.getPreviewSize().width * params.getPreviewSize().height;
@ -123,11 +123,11 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
mFrame = new byte [size]; mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer); mCamera.addCallbackBuffer(mBuffer);
try { try {
setPreview(); setPreview();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
} }
/* Notify that the preview is about to be started and deliver preview size */ /* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height); onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);
@ -137,7 +137,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

@ -12,6 +12,7 @@ import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
public class Sample4Mixed extends Activity { public class Sample4Mixed extends Activity {
private static final String TAG = "Sample::Activity"; private static final String TAG = "Sample::Activity";
@ -20,103 +21,91 @@ public class Sample4Mixed extends Activity {
private MenuItem mItemPreviewGray; private MenuItem mItemPreviewGray;
private MenuItem mItemPreviewCanny; private MenuItem mItemPreviewCanny;
private MenuItem mItemPreviewFeatures; private MenuItem mItemPreviewFeatures;
private Sample4View mView; private Sample4View mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
switch (status) { switch (status) {
case LoaderCallbackInterface.SUCCESS: case LoaderCallbackInterface.SUCCESS:
{ {
Log.i(TAG, "OpenCV loaded successfully"); Log.i(TAG, "OpenCV loaded successfully");
// Load native library after(!) OpenCV initialization // Load native library after(!) OpenCV initialization
System.loadLibrary("mixed_sample"); System.loadLibrary("mixed_sample");
// Create and set View // Create and set View
mView = new Sample4View(mAppContext); mView = new Sample4View(mAppContext);
setContentView(mView); setContentView(mView);
// Check native OpenCV camera // Check native OpenCV camera
if( !mView.openCamera() ) { if( !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(mAppContext).create(); AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
ad.setCancelable(false); // This blocks the 'BACK' button ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!"); ad.setMessage("Fatal error: can't open camera!");
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); finish();
} }
}); });
ad.show(); ad.show();
} }
} break; } break;
/** OpenCV loader cannot start Google Play **/ /** OpenCV loader cannot start Google Play **/
case LoaderCallbackInterface.MARKET_ERROR: case LoaderCallbackInterface.MARKET_ERROR:
{ {
Log.d(TAG, "Google Play service is not accessible!"); Log.d(TAG, "Google Play service is not accessible!");
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create(); AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
MarketErrorMessage.setTitle("OpenCV Manager"); 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.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.setCancelable(false); // This blocks the 'BACK' button
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mAppContext.finish(); mAppContext.finish();
} }
}); });
MarketErrorMessage.show(); MarketErrorMessage.show();
} break; } break;
default: default:
{ {
super.onManagerConnected(status); super.onManagerConnected(status);
} break; } break;
} }
} }
}; };
public Sample4Mixed() { public Sample4Mixed() {
Log.i(TAG, "Instantiated new " + this.getClass()); Log.i(TAG, "Instantiated new " + this.getClass());
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.i(TAG, "onPause"); Log.i(TAG, "onPause");
super.onPause(); if (null != mView)
if (null != mView) mView.releaseCamera();
mView.releaseCamera(); super.onPause();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.i(TAG, "onResume"); Log.i(TAG, "onResume");
super.onResume(); super.onResume();
if((null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create(); Log.i(TAG, "Trying to load OpenCV library");
ad.setCancelable(false); // This blocks the 'BACK' button if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
ad.setMessage("Fatal error: can't open camera!"); {
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { Log.e(TAG, "Cannot connect to OpenCV Manager");
public void onClick(DialogInterface dialog, int which) { }
dialog.dismiss(); }
finish();
}
});
ad.show();
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate"); Log.i(TAG, "onCreate");
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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");
}
} }
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
@ -131,13 +120,13 @@ public class Sample4Mixed extends Activity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "Menu Item selected " + item); Log.i(TAG, "Menu Item selected " + item);
if (item == mItemPreviewRGBA) { if (item == mItemPreviewRGBA) {
mView.setViewMode(Sample4View.VIEW_MODE_RGBA); mView.setViewMode(Sample4View.VIEW_MODE_RGBA);
} else if (item == mItemPreviewGray) { } else if (item == mItemPreviewGray) {
mView.setViewMode(Sample4View.VIEW_MODE_GRAY); mView.setViewMode(Sample4View.VIEW_MODE_GRAY);
} else if (item == mItemPreviewCanny) { } else if (item == mItemPreviewCanny) {
mView.setViewMode(Sample4View.VIEW_MODE_CANNY); mView.setViewMode(Sample4View.VIEW_MODE_CANNY);
} else if (item == mItemPreviewFeatures) { } else if (item == mItemPreviewFeatures) {
mView.setViewMode(Sample4View.VIEW_MODE_FEATURES); mView.setViewMode(Sample4View.VIEW_MODE_FEATURES);
} }
return true; return true;
} }

@ -15,39 +15,39 @@ class Sample4View extends SampleViewBase {
public static final int VIEW_MODE_GRAY = 1; public static final int VIEW_MODE_GRAY = 1;
public static final int VIEW_MODE_CANNY = 2; public static final int VIEW_MODE_CANNY = 2;
public static final int VIEW_MODE_FEATURES = 5; public static final int VIEW_MODE_FEATURES = 5;
private Mat mYuv; private Mat mYuv;
private Mat mRgba; private Mat mRgba;
private Mat mGraySubmat; private Mat mGraySubmat;
private Mat mIntermediateMat; private Mat mIntermediateMat;
private int mViewMode; private int mViewMode;
private Bitmap mBitmap; private Bitmap mBitmap;
public Sample4View(Context context) { public Sample4View(Context context) {
super(context); super(context);
} }
@Override @Override
protected void onPreviewStarted(int previewWidtd, int previewHeight) { protected void onPreviewStarted(int previewWidtd, int previewHeight) {
// initialize Mats before usage // initialize Mats before usage
mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1); mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth()); mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth());
mRgba = new Mat(); mRgba = new Mat();
mIntermediateMat = new Mat(); mIntermediateMat = new Mat();
mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888); mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888);
} }
@Override @Override
protected void onPreviewStopped() { protected void onPreviewStopped() {
if (mBitmap != null) { if (mBitmap != null) {
mBitmap.recycle(); mBitmap.recycle();
mBitmap = null; mBitmap = null;
} }
// Explicitly deallocate Mats // Explicitly deallocate Mats
if (mYuv != null) if (mYuv != null)
mYuv.release(); mYuv.release();
@ -62,8 +62,8 @@ class Sample4View extends SampleViewBase {
mRgba = null; mRgba = null;
mGraySubmat = null; mGraySubmat = null;
mIntermediateMat = null; mIntermediateMat = null;
} }
@Override @Override
@ -105,6 +105,6 @@ class Sample4View extends SampleViewBase {
public native void FindFeatures(long matAddrGr, long matAddrRgba); public native void FindFeatures(long matAddrGr, long matAddrRgba);
public void setViewMode(int viewMode) { public void setViewMode(int viewMode) {
mViewMode = viewMode; mViewMode = viewMode;
} }
} }

@ -45,35 +45,35 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
mCamera.setPreviewTexture( new SurfaceTexture(10) ); mCamera.setPreviewTexture( new SurfaceTexture(10) );
else else
mCamera.setPreviewDisplay(null); mCamera.setPreviewDisplay(null);
} }
public boolean openCamera() { public boolean openCamera() {
Log.i(TAG, "openCamera"); Log.i(TAG, "openCamera");
releaseCamera(); releaseCamera();
mCamera = Camera.open(); mCamera = Camera.open();
if(mCamera == null) { if(mCamera == null) {
Log.e(TAG, "Can't open camera!"); Log.e(TAG, "Can't open camera!");
return false; return false;
} }
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() { mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) { public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) { synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length); System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify(); SampleViewBase.this.notify();
} }
camera.addCallbackBuffer(mBuffer); camera.addCallbackBuffer(mBuffer);
} }
}); });
return true; return true;
} }
public void releaseCamera() { public void releaseCamera() {
Log.i(TAG, "releaseCamera"); Log.i(TAG, "releaseCamera");
mThreadRun = false; mThreadRun = false;
synchronized (this) { synchronized (this) {
if (mCamera != null) { if (mCamera != null) {
mCamera.stopPreview(); mCamera.stopPreview();
mCamera.setPreviewCallback(null); mCamera.setPreviewCallback(null);
mCamera.release(); mCamera.release();
@ -82,7 +82,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
onPreviewStopped(); onPreviewStopped();
} }
public void setupCamera(int width, int height) { public void setupCamera(int width, int height) {
Log.i(TAG, "setupCamera"); Log.i(TAG, "setupCamera");
synchronized (this) { synchronized (this) {
@ -105,15 +105,15 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
params.setPreviewSize(getFrameWidth(), getFrameHeight()); params.setPreviewSize(getFrameWidth(), getFrameHeight());
List<String> FocusModes = params.getSupportedFocusModes(); List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{ {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} }
mCamera.setParameters(params); mCamera.setParameters(params);
/* Now allocate the buffer */ /* Now allocate the buffer */
params = mCamera.getParameters(); params = mCamera.getParameters();
int size = params.getPreviewSize().width * params.getPreviewSize().height; int size = params.getPreviewSize().width * params.getPreviewSize().height;
@ -123,11 +123,11 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
mFrame = new byte [size]; mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer); mCamera.addCallbackBuffer(mBuffer);
try { try {
setPreview(); setPreview();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
} }
/* Notify that the preview is about to be started and deliver preview size */ /* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height); onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);
@ -137,7 +137,7 @@ public abstract class SampleViewBase extends SurfaceView implements SurfaceHolde
} }
} }
} }
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceChanged"); Log.i(TAG, "surfaceChanged");
setupCamera(width, height); setupCamera(width, height);

Loading…
Cancel
Save