Color blob detection sample ported on new framework.
This commit is contained in:
parent
2fd8b51a26
commit
c64ee44c9e
@ -0,0 +1,11 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" >
|
||||||
|
|
||||||
|
<org.opencv.framework.OpenCvJavaCameraView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:id="@+id/color_blob_detection_activity_surface_view" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -1,62 +1,53 @@
|
|||||||
package org.opencv.samples.colorblobdetect;
|
package org.opencv.samples.colorblobdetect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.opencv.android.BaseLoaderCallback;
|
import org.opencv.android.BaseLoaderCallback;
|
||||||
import org.opencv.android.LoaderCallbackInterface;
|
import org.opencv.android.LoaderCallbackInterface;
|
||||||
import org.opencv.android.OpenCVLoader;
|
import org.opencv.android.OpenCVLoader;
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
import org.opencv.core.CvType;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.core.MatOfPoint;
|
||||||
|
import org.opencv.core.Rect;
|
||||||
|
import org.opencv.core.Scalar;
|
||||||
|
import org.opencv.core.Size;
|
||||||
|
import org.opencv.framework.OpenCvCameraBridgeViewBase.CvCameraViewListener;
|
||||||
|
import org.opencv.framework.OpenCvJavaCameraView;
|
||||||
|
import org.opencv.imgproc.Imgproc;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.View.OnTouchListener;
|
||||||
|
|
||||||
public class ColorBlobDetectionActivity extends Activity {
|
public class ColorBlobDetectionActivity extends Activity implements OnTouchListener, CvCameraViewListener {
|
||||||
private static final String TAG = "OCVSample::Activity";
|
private static final String TAG = "OCVSample::Activity";
|
||||||
|
|
||||||
private ColorBlobDetectionView mView;
|
private boolean mIsColorSelected = false;
|
||||||
|
private Mat mRgba;
|
||||||
|
private Scalar mBlobColorRgba;
|
||||||
|
private Scalar mBlobColorHsv;
|
||||||
|
private ColorBlobDetector mDetector;
|
||||||
|
private Mat mSpectrum;
|
||||||
|
private Size SPECTRUM_SIZE;
|
||||||
|
private Scalar CONTOUR_COLOR;
|
||||||
|
|
||||||
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
|
private OpenCvJavaCameraView mOpenCvCameraView;
|
||||||
|
|
||||||
|
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||||
@Override
|
@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
|
mOpenCvCameraView.enableView();
|
||||||
mView = new ColorBlobDetectionView(mAppContext);
|
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
|
||||||
setContentView(mView);
|
|
||||||
|
|
||||||
// Check native OpenCV camera
|
|
||||||
if( !mView.openCamera() ) {
|
|
||||||
AlertDialog ad = new AlertDialog.Builder(mAppContext).create();
|
|
||||||
ad.setCancelable(false); // This blocks the 'BACK' button
|
|
||||||
ad.setMessage("Fatal error: can't open camera!");
|
|
||||||
ad.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
dialog.dismiss();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ad.show();
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
/** OpenCV loader cannot start Google Play **/
|
|
||||||
case LoaderCallbackInterface.MARKET_ERROR:
|
|
||||||
{
|
|
||||||
Log.d(TAG, "Google Play service is not accessible!");
|
|
||||||
AlertDialog MarketErrorMessage = new AlertDialog.Builder(mAppContext).create();
|
|
||||||
MarketErrorMessage.setTitle("OpenCV Manager");
|
|
||||||
MarketErrorMessage.setMessage("Google Play service is not accessible!\nTry to install the 'OpenCV Manager' and the appropriate 'OpenCV binary pack' APKs from OpenCV SDK manually via 'adb install' command.");
|
|
||||||
MarketErrorMessage.setCancelable(false); // This blocks the 'BACK' button
|
|
||||||
MarketErrorMessage.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
MarketErrorMessage.show();
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -70,25 +61,6 @@ public class ColorBlobDetectionActivity extends Activity {
|
|||||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
Log.i(TAG, "called onPause");
|
|
||||||
if (null != mView)
|
|
||||||
mView.releaseCamera();
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
Log.i(TAG, "called onResume");
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
Log.i(TAG, "Trying to load OpenCV library");
|
|
||||||
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) {
|
|
||||||
Log.e(TAG, "Cannot connect to OpenCV Manager");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -96,5 +68,117 @@ public class ColorBlobDetectionActivity extends Activity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
setContentView(R.layout.color_blob_detection_surface_view);
|
||||||
|
|
||||||
|
mOpenCvCameraView = (OpenCvJavaCameraView)findViewById(R.id.color_blob_detection_activity_surface_view);
|
||||||
|
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
mOpenCvCameraView.disableView();
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume()
|
||||||
|
{
|
||||||
|
super.onResume();
|
||||||
|
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
mOpenCvCameraView.disableView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCameraViewStarted(int width, int height) {
|
||||||
|
mRgba = new Mat(height, width, CvType.CV_8UC4);
|
||||||
|
mDetector = new ColorBlobDetector();
|
||||||
|
mSpectrum = new Mat();
|
||||||
|
mBlobColorRgba = new Scalar(255);
|
||||||
|
mBlobColorHsv = new Scalar(255);
|
||||||
|
SPECTRUM_SIZE = new Size(200, 32);
|
||||||
|
CONTOUR_COLOR = new Scalar(255,0,0,255);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCameraViewStopped() {
|
||||||
|
mRgba.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
int cols = mRgba.cols();
|
||||||
|
int rows = mRgba.rows();
|
||||||
|
|
||||||
|
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
|
||||||
|
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
|
||||||
|
|
||||||
|
int x = (int)event.getX() - xOffset;
|
||||||
|
int y = (int)event.getY() - yOffset;
|
||||||
|
|
||||||
|
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
|
||||||
|
|
||||||
|
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
|
||||||
|
|
||||||
|
Rect touchedRect = new Rect();
|
||||||
|
|
||||||
|
touchedRect.x = (x>4) ? x-4 : 0;
|
||||||
|
touchedRect.y = (y>4) ? y-4 : 0;
|
||||||
|
|
||||||
|
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
|
||||||
|
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
|
||||||
|
|
||||||
|
Mat touchedRegionRgba = mRgba.submat(touchedRect);
|
||||||
|
|
||||||
|
Mat touchedRegionHsv = new Mat();
|
||||||
|
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
|
||||||
|
|
||||||
|
// Calculate average color of touched region
|
||||||
|
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
|
||||||
|
int pointCount = touchedRect.width*touchedRect.height;
|
||||||
|
for (int i = 0; i < mBlobColorHsv.val.length; i++)
|
||||||
|
mBlobColorHsv.val[i] /= pointCount;
|
||||||
|
|
||||||
|
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
|
||||||
|
|
||||||
|
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
|
||||||
|
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
|
||||||
|
|
||||||
|
mDetector.setHsvColor(mBlobColorHsv);
|
||||||
|
|
||||||
|
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
|
||||||
|
|
||||||
|
mIsColorSelected = true;
|
||||||
|
|
||||||
|
return false; // don't need subsequent touch events
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mat onCameraFrame(Mat inputFrame) {
|
||||||
|
inputFrame.copyTo(mRgba);
|
||||||
|
|
||||||
|
if (mIsColorSelected) {
|
||||||
|
mDetector.process(mRgba);
|
||||||
|
List<MatOfPoint> contours = mDetector.getContours();
|
||||||
|
Log.e(TAG, "Contours count: " + contours.size());
|
||||||
|
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
|
||||||
|
|
||||||
|
Mat colorLabel = mRgba.submat(2, 34, 2, 34);
|
||||||
|
colorLabel.setTo(mBlobColorRgba);
|
||||||
|
|
||||||
|
Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols());
|
||||||
|
mSpectrum.copyTo(spectrumLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mRgba;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
|
||||||
|
Mat pointMatRgba = new Mat();
|
||||||
|
Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
|
||||||
|
Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
|
||||||
|
|
||||||
|
return new Scalar(pointMatRgba.get(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,151 +0,0 @@
|
|||||||
package org.opencv.samples.colorblobdetect;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.opencv.android.Utils;
|
|
||||||
import org.opencv.core.Core;
|
|
||||||
import org.opencv.core.CvType;
|
|
||||||
import org.opencv.core.Mat;
|
|
||||||
import org.opencv.core.MatOfPoint;
|
|
||||||
import org.opencv.core.Rect;
|
|
||||||
import org.opencv.core.Scalar;
|
|
||||||
import org.opencv.core.Size;
|
|
||||||
import org.opencv.highgui.Highgui;
|
|
||||||
import org.opencv.highgui.VideoCapture;
|
|
||||||
import org.opencv.imgproc.Imgproc;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
|
|
||||||
public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchListener {
|
|
||||||
private static final String TAG = "OCVSample::View";
|
|
||||||
|
|
||||||
private Mat mRgba;
|
|
||||||
private boolean mIsColorSelected = false;
|
|
||||||
private Scalar mBlobColorRgba = new Scalar(255);
|
|
||||||
private Scalar mBlobColorHsv = new Scalar(255);
|
|
||||||
private ColorBlobDetector mDetector = new ColorBlobDetector();
|
|
||||||
private Mat mSpectrum = new Mat();
|
|
||||||
private static Size SPECTRUM_SIZE = new Size(200, 32);
|
|
||||||
private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255);
|
|
||||||
|
|
||||||
|
|
||||||
public ColorBlobDetectionView(Context context) {
|
|
||||||
super(context);
|
|
||||||
setOnTouchListener(this);
|
|
||||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
|
||||||
Log.i(TAG, "called surfaceCreated");
|
|
||||||
synchronized (this) {
|
|
||||||
// initialize Mat before usage
|
|
||||||
mRgba = new Mat();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.surfaceCreated(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Scalar converScalarHsv2Rgba(Scalar hsvColor) {
|
|
||||||
Mat pointMatRgba = new Mat();
|
|
||||||
Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
|
|
||||||
Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
|
|
||||||
|
|
||||||
return new Scalar(pointMatRgba.get(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
int cols = mRgba.cols();
|
|
||||||
int rows = mRgba.rows();
|
|
||||||
|
|
||||||
int xOffset = (getWidth() - cols) / 2;
|
|
||||||
int yOffset = (getHeight() - rows) / 2;
|
|
||||||
|
|
||||||
int x = (int)event.getX() - xOffset;
|
|
||||||
int y = (int)event.getY() - yOffset;
|
|
||||||
|
|
||||||
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
|
|
||||||
|
|
||||||
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
|
|
||||||
|
|
||||||
Rect touchedRect = new Rect();
|
|
||||||
|
|
||||||
touchedRect.x = (x>4) ? x-4 : 0;
|
|
||||||
touchedRect.y = (y>4) ? y-4 : 0;
|
|
||||||
|
|
||||||
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
|
|
||||||
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
|
|
||||||
|
|
||||||
Mat touchedRegionRgba = mRgba.submat(touchedRect);
|
|
||||||
|
|
||||||
Mat touchedRegionHsv = new Mat();
|
|
||||||
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
|
|
||||||
|
|
||||||
// Calculate average color of touched region
|
|
||||||
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
|
|
||||||
int pointCount = touchedRect.width*touchedRect.height;
|
|
||||||
for (int i = 0; i < mBlobColorHsv.val.length; i++)
|
|
||||||
mBlobColorHsv.val[i] /= pointCount;
|
|
||||||
|
|
||||||
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
|
|
||||||
|
|
||||||
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
|
|
||||||
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
|
|
||||||
|
|
||||||
mDetector.setHsvColor(mBlobColorHsv);
|
|
||||||
|
|
||||||
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
|
|
||||||
|
|
||||||
mIsColorSelected = true;
|
|
||||||
|
|
||||||
return false; // don't need subsequent touch events
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Bitmap processFrame(VideoCapture capture) {
|
|
||||||
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
|
|
||||||
|
|
||||||
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
|
|
||||||
|
|
||||||
if (mIsColorSelected) {
|
|
||||||
mDetector.process(mRgba);
|
|
||||||
List<MatOfPoint> contours = mDetector.getContours();
|
|
||||||
Log.e(TAG, "Contours count: " + contours.size());
|
|
||||||
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
|
|
||||||
|
|
||||||
Mat colorLabel = mRgba.submat(2, 34, 2, 34);
|
|
||||||
colorLabel.setTo(mBlobColorRgba);
|
|
||||||
|
|
||||||
Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols());
|
|
||||||
mSpectrum.copyTo(spectrumLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Utils.matToBitmap(mRgba, bmp);
|
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
|
|
||||||
bmp.recycle();
|
|
||||||
bmp = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
super.run();
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
// Explicitly deallocate Mats
|
|
||||||
if (mRgba != null)
|
|
||||||
mRgba.release();
|
|
||||||
|
|
||||||
mRgba = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package org.opencv.samples.colorblobdetect;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.opencv.core.Size;
|
|
||||||
import org.opencv.highgui.VideoCapture;
|
|
||||||
import org.opencv.highgui.Highgui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
|
|
||||||
public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable {
|
|
||||||
private static final String TAG = "OCVSample::BaseView";
|
|
||||||
|
|
||||||
private SurfaceHolder mHolder;
|
|
||||||
private VideoCapture mCamera;
|
|
||||||
|
|
||||||
public SampleCvViewBase(Context context) {
|
|
||||||
super(context);
|
|
||||||
mHolder = getHolder();
|
|
||||||
mHolder.addCallback(this);
|
|
||||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized boolean openCamera() {
|
|
||||||
Log.i(TAG, "Opening Camera");
|
|
||||||
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
|
|
||||||
if (!mCamera.isOpened()) {
|
|
||||||
releaseCamera();
|
|
||||||
Log.e(TAG, "Can't open native camera");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void releaseCamera() {
|
|
||||||
Log.i(TAG, "Releasing Camera");
|
|
||||||
if (mCamera != null) {
|
|
||||||
mCamera.release();
|
|
||||||
mCamera = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void setupCamera(int width, int height) {
|
|
||||||
if (mCamera != null && mCamera.isOpened()) {
|
|
||||||
Log.i(TAG, "Setup Camera - " + width + "x" + height);
|
|
||||||
List<Size> sizes = mCamera.getSupportedPreviewSizes();
|
|
||||||
int mFrameWidth = width;
|
|
||||||
int mFrameHeight = height;
|
|
||||||
|
|
||||||
// selecting optimal camera preview size
|
|
||||||
{
|
|
||||||
double minDiff = Double.MAX_VALUE;
|
|
||||||
for (Size size : sizes) {
|
|
||||||
if (Math.abs(size.height - height) < minDiff) {
|
|
||||||
mFrameWidth = (int) size.width;
|
|
||||||
mFrameHeight = (int) size.height;
|
|
||||||
minDiff = Math.abs(size.height - height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth);
|
|
||||||
mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
|
|
||||||
Log.i(TAG, "called surfaceChanged");
|
|
||||||
setupCamera(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
|
||||||
Log.i(TAG, "called surfaceCreated");
|
|
||||||
(new Thread(this)).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
||||||
Log.i(TAG, "called surfaceDestroyed");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Bitmap processFrame(VideoCapture capture);
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
Log.i(TAG, "Started processing thread");
|
|
||||||
while (true) {
|
|
||||||
Bitmap bmp = null;
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
if (mCamera == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!mCamera.grab()) {
|
|
||||||
Log.e(TAG, "mCamera.grab() failed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bmp = processFrame(mCamera);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bmp != null) {
|
|
||||||
Canvas canvas = mHolder.lockCanvas();
|
|
||||||
if (canvas != null) {
|
|
||||||
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
|
|
||||||
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
|
|
||||||
mHolder.unlockCanvasAndPost(canvas);
|
|
||||||
}
|
|
||||||
bmp.recycle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.i(TAG, "Finished processing thread");
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user