Face detection sample ported on new framework.
This commit is contained in:
		
				
					committed by
					
						
						Andrey Kamaev
					
				
			
			
				
	
			
			
			
						parent
						
							d9ea16ce57
						
					
				
				
					commit
					2fd8b51a26
				
			@@ -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/fd_activity_surface_view" />
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@@ -1,12 +1,26 @@
 | 
			
		||||
package org.opencv.samples.fd;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import org.opencv.android.BaseLoaderCallback;
 | 
			
		||||
import org.opencv.android.LoaderCallbackInterface;
 | 
			
		||||
import org.opencv.android.OpenCVLoader;
 | 
			
		||||
import org.opencv.core.Core;
 | 
			
		||||
import org.opencv.core.Mat;
 | 
			
		||||
import org.opencv.core.MatOfRect;
 | 
			
		||||
import org.opencv.core.Rect;
 | 
			
		||||
import org.opencv.core.Scalar;
 | 
			
		||||
import org.opencv.core.Size;
 | 
			
		||||
import org.opencv.framework.OpenCvJavaCameraView;
 | 
			
		||||
import org.opencv.framework.OpenCvCameraBridgeViewBase.CvCameraViewListener;
 | 
			
		||||
import org.opencv.imgproc.Imgproc;
 | 
			
		||||
import org.opencv.objdetect.CascadeClassifier;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.app.AlertDialog;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
@@ -14,19 +28,34 @@ import android.view.MenuItem;
 | 
			
		||||
import android.view.Window;
 | 
			
		||||
import android.view.WindowManager;
 | 
			
		||||
 | 
			
		||||
public class FdActivity extends Activity {
 | 
			
		||||
    private static final String TAG             = "OCVSample::Activity";
 | 
			
		||||
public class FdActivity extends Activity implements CvCameraViewListener {
 | 
			
		||||
 | 
			
		||||
    private MenuItem            mItemFace50;
 | 
			
		||||
    private MenuItem            mItemFace40;
 | 
			
		||||
    private MenuItem            mItemFace30;
 | 
			
		||||
    private MenuItem            mItemFace20;
 | 
			
		||||
    private MenuItem            mItemType;
 | 
			
		||||
    private int                 mDetectorType = 0;
 | 
			
		||||
    private String[]            mDetectorName;
 | 
			
		||||
    private FdView              mView;
 | 
			
		||||
    private static final String    TAG                 = "OCVSample::Activity";
 | 
			
		||||
    private static final Scalar    FACE_RECT_COLOR     = new Scalar(0, 255, 0, 255);
 | 
			
		||||
    public static final int        JAVA_DETECTOR       = 0;
 | 
			
		||||
    public static final int        NATIVE_DETECTOR     = 1;
 | 
			
		||||
 | 
			
		||||
    private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
 | 
			
		||||
    private MenuItem               mItemFace50;
 | 
			
		||||
    private MenuItem               mItemFace40;
 | 
			
		||||
    private MenuItem               mItemFace30;
 | 
			
		||||
    private MenuItem               mItemFace20;
 | 
			
		||||
    private MenuItem               mItemType;
 | 
			
		||||
 | 
			
		||||
    private Mat                    mRgba;
 | 
			
		||||
    private Mat                    mGray;
 | 
			
		||||
    private File                   mCascadeFile;
 | 
			
		||||
    private CascadeClassifier      mJavaDetector;
 | 
			
		||||
    private DetectionBasedTracker  mNativeDetector;
 | 
			
		||||
 | 
			
		||||
    private int                    mDetectorType       = JAVA_DETECTOR;
 | 
			
		||||
    private String[]               mDetectorName;
 | 
			
		||||
 | 
			
		||||
    private float                  mRelativeFaceSize   = 0;
 | 
			
		||||
    private int                    mAbsoluteFaceSize   = 0;
 | 
			
		||||
 | 
			
		||||
    private OpenCvJavaCameraView   mOpenCvCameraView;
 | 
			
		||||
 | 
			
		||||
    private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onManagerConnected(int status) {
 | 
			
		||||
            switch (status) {
 | 
			
		||||
@@ -34,44 +63,41 @@ public class FdActivity extends Activity {
 | 
			
		||||
                {
 | 
			
		||||
                    Log.i(TAG, "OpenCV loaded successfully");
 | 
			
		||||
 | 
			
		||||
                    // Load native libs after OpenCV initialization
 | 
			
		||||
                    // Load native library after(!) OpenCV initialization
 | 
			
		||||
                    System.loadLibrary("detection_based_tracker");
 | 
			
		||||
 | 
			
		||||
                    // Create and set View
 | 
			
		||||
                    mView = new FdView(mAppContext);
 | 
			
		||||
                    mView.setDetectorType(mDetectorType);
 | 
			
		||||
                    mView.setMinFaceSize(0.2f);
 | 
			
		||||
                    setContentView(mView);
 | 
			
		||||
                    try {
 | 
			
		||||
                        // load cascade file from application resources
 | 
			
		||||
                        InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
 | 
			
		||||
                        File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
 | 
			
		||||
                        mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
 | 
			
		||||
                        FileOutputStream os = new FileOutputStream(mCascadeFile);
 | 
			
		||||
 | 
			
		||||
                    // 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();
 | 
			
		||||
                        byte[] buffer = new byte[4096];
 | 
			
		||||
                        int bytesRead;
 | 
			
		||||
                        while ((bytesRead = is.read(buffer)) != -1) {
 | 
			
		||||
                            os.write(buffer, 0, bytesRead);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    MarketErrorMessage.show();
 | 
			
		||||
                        is.close();
 | 
			
		||||
                        os.close();
 | 
			
		||||
 | 
			
		||||
                        mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath());
 | 
			
		||||
                        if (mJavaDetector.empty()) {
 | 
			
		||||
                            Log.e(TAG, "Failed to load cascade classifier");
 | 
			
		||||
                            mJavaDetector = null;
 | 
			
		||||
                        } else
 | 
			
		||||
                            Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());
 | 
			
		||||
 | 
			
		||||
                        mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
 | 
			
		||||
 | 
			
		||||
                        cascadeDir.delete();
 | 
			
		||||
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                        Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    mOpenCvCameraView.enableView();
 | 
			
		||||
                } break;
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
@@ -83,30 +109,12 @@ public class FdActivity extends Activity {
 | 
			
		||||
 | 
			
		||||
    public FdActivity() {
 | 
			
		||||
        mDetectorName = new String[2];
 | 
			
		||||
        mDetectorName[FdView.JAVA_DETECTOR] = "Java";
 | 
			
		||||
        mDetectorName[FdView.NATIVE_DETECTOR] = "Native (tracking)";
 | 
			
		||||
        mDetectorName[JAVA_DETECTOR] = "Java";
 | 
			
		||||
        mDetectorName[NATIVE_DETECTOR] = "Native (tracking)";
 | 
			
		||||
 | 
			
		||||
        Log.i(TAG, "Instantiated new " + this.getClass());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPause() {
 | 
			
		||||
        Log.i(TAG, "called onPause");
 | 
			
		||||
        if (null != mView)
 | 
			
		||||
            mView.releaseCamera();
 | 
			
		||||
        super.onPause();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onResume() {
 | 
			
		||||
        Log.i(TAG, "called onResume");
 | 
			
		||||
        super.onResume();
 | 
			
		||||
 | 
			
		||||
        Log.i(TAG, "Trying to load OpenCV library");
 | 
			
		||||
        if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack)) {
 | 
			
		||||
            Log.e(TAG, "Cannot connect to OpenCV Manager");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Called when the activity is first created. */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
@@ -114,6 +122,75 @@ public class FdActivity extends Activity {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        requestWindowFeature(Window.FEATURE_NO_TITLE);
 | 
			
		||||
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
 | 
			
		||||
 | 
			
		||||
        setContentView(R.layout.face_detect_surface_view);
 | 
			
		||||
 | 
			
		||||
        mOpenCvCameraView = (OpenCvJavaCameraView)findViewById(R.id.fd_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) {
 | 
			
		||||
        mGray = new Mat();
 | 
			
		||||
        mRgba = new Mat();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onCameraViewStopped() {
 | 
			
		||||
        mGray.release();
 | 
			
		||||
        mRgba.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Mat onCameraFrame(Mat inputFrame) {
 | 
			
		||||
 | 
			
		||||
        inputFrame.copyTo(mRgba);
 | 
			
		||||
        Imgproc.cvtColor(inputFrame, mGray, Imgproc.COLOR_RGBA2GRAY);
 | 
			
		||||
 | 
			
		||||
        if (mAbsoluteFaceSize == 0) {
 | 
			
		||||
            int height = mGray.rows();
 | 
			
		||||
            if (Math.round(height * mRelativeFaceSize) > 0) {
 | 
			
		||||
                mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
 | 
			
		||||
            }
 | 
			
		||||
            mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MatOfRect faces = new MatOfRect();
 | 
			
		||||
 | 
			
		||||
        if (mDetectorType == JAVA_DETECTOR) {
 | 
			
		||||
            if (mJavaDetector != null)
 | 
			
		||||
                mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
 | 
			
		||||
                        new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
 | 
			
		||||
        }
 | 
			
		||||
        else if (mDetectorType == NATIVE_DETECTOR) {
 | 
			
		||||
            if (mNativeDetector != null)
 | 
			
		||||
                mNativeDetector.detect(mGray, faces);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            Log.e(TAG, "Detection method is not selected!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rect[] facesArray = faces.toArray();
 | 
			
		||||
        for (int i = 0; i < facesArray.length; i++)
 | 
			
		||||
            Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
 | 
			
		||||
 | 
			
		||||
        return mRgba;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -131,18 +208,37 @@ public class FdActivity extends Activity {
 | 
			
		||||
    public boolean onOptionsItemSelected(MenuItem item) {
 | 
			
		||||
        Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
 | 
			
		||||
        if (item == mItemFace50)
 | 
			
		||||
            mView.setMinFaceSize(0.5f);
 | 
			
		||||
            setMinFaceSize(0.5f);
 | 
			
		||||
        else if (item == mItemFace40)
 | 
			
		||||
            mView.setMinFaceSize(0.4f);
 | 
			
		||||
            setMinFaceSize(0.4f);
 | 
			
		||||
        else if (item == mItemFace30)
 | 
			
		||||
            mView.setMinFaceSize(0.3f);
 | 
			
		||||
            setMinFaceSize(0.3f);
 | 
			
		||||
        else if (item == mItemFace20)
 | 
			
		||||
            mView.setMinFaceSize(0.2f);
 | 
			
		||||
            setMinFaceSize(0.2f);
 | 
			
		||||
        else if (item == mItemType) {
 | 
			
		||||
            mDetectorType = (mDetectorType + 1) % mDetectorName.length;
 | 
			
		||||
            item.setTitle(mDetectorName[mDetectorType]);
 | 
			
		||||
            mView.setDetectorType(mDetectorType);
 | 
			
		||||
            setDetectorType(mDetectorType);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setMinFaceSize(float faceSize) {
 | 
			
		||||
        mRelativeFaceSize = faceSize;
 | 
			
		||||
        mAbsoluteFaceSize = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setDetectorType(int type) {
 | 
			
		||||
        if (mDetectorType != type) {
 | 
			
		||||
            mDetectorType = type;
 | 
			
		||||
 | 
			
		||||
            if (type == NATIVE_DETECTOR) {
 | 
			
		||||
                Log.i(TAG, "Detection Based Tracker enabled");
 | 
			
		||||
                mNativeDetector.start();
 | 
			
		||||
            } else {
 | 
			
		||||
                Log.i(TAG, "Cascade detector enabled");
 | 
			
		||||
                mNativeDetector.stop();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,175 +0,0 @@
 | 
			
		||||
package org.opencv.samples.fd;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import org.opencv.android.Utils;
 | 
			
		||||
import org.opencv.core.Core;
 | 
			
		||||
import org.opencv.core.Mat;
 | 
			
		||||
import org.opencv.core.MatOfRect;
 | 
			
		||||
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.objdetect.CascadeClassifier;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.SurfaceHolder;
 | 
			
		||||
 | 
			
		||||
class FdView extends SampleCvViewBase {
 | 
			
		||||
    private static final String     TAG                 = "OCVSample::View";
 | 
			
		||||
    private Mat                     mRgba;
 | 
			
		||||
    private Mat                     mGray;
 | 
			
		||||
    private File                    mCascadeFile;
 | 
			
		||||
    private CascadeClassifier       mJavaDetector;
 | 
			
		||||
    private DetectionBasedTracker   mNativeDetector;
 | 
			
		||||
 | 
			
		||||
    private static final Scalar     FACE_RECT_COLOR     = new Scalar(0, 255, 0, 255);
 | 
			
		||||
 | 
			
		||||
    public static final int         JAVA_DETECTOR       = 0;
 | 
			
		||||
    public static final int         NATIVE_DETECTOR     = 1;
 | 
			
		||||
 | 
			
		||||
    private int                     mDetectorType       = JAVA_DETECTOR;
 | 
			
		||||
 | 
			
		||||
    private float                   mRelativeFaceSize   = 0;
 | 
			
		||||
    private int                     mAbsoluteFaceSize   = 0;
 | 
			
		||||
 | 
			
		||||
    public void setMinFaceSize(float faceSize) {
 | 
			
		||||
        mRelativeFaceSize = faceSize;
 | 
			
		||||
        mAbsoluteFaceSize = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setDetectorType(int type) {
 | 
			
		||||
        if (mDetectorType != type) {
 | 
			
		||||
            mDetectorType = type;
 | 
			
		||||
 | 
			
		||||
            if (type == NATIVE_DETECTOR) {
 | 
			
		||||
                Log.i(TAG, "Detection Based Tracker enabled");
 | 
			
		||||
                mNativeDetector.start();
 | 
			
		||||
            } else {
 | 
			
		||||
                Log.i(TAG, "Cascade detector enabled");
 | 
			
		||||
                mNativeDetector.stop();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public FdView(Context context) {
 | 
			
		||||
        super(context);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // load cascade file from application resources
 | 
			
		||||
            InputStream is = context.getResources().openRawResource(R.raw.lbpcascade_frontalface);
 | 
			
		||||
            File cascadeDir = context.getDir("cascade", Context.MODE_PRIVATE);
 | 
			
		||||
            mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
 | 
			
		||||
            FileOutputStream os = new FileOutputStream(mCascadeFile);
 | 
			
		||||
 | 
			
		||||
            byte[] buffer = new byte[4096];
 | 
			
		||||
            int bytesRead;
 | 
			
		||||
            while ((bytesRead = is.read(buffer)) != -1) {
 | 
			
		||||
                os.write(buffer, 0, bytesRead);
 | 
			
		||||
            }
 | 
			
		||||
            is.close();
 | 
			
		||||
            os.close();
 | 
			
		||||
 | 
			
		||||
            mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath());
 | 
			
		||||
            if (mJavaDetector.empty()) {
 | 
			
		||||
                Log.e(TAG, "Failed to load cascade classifier");
 | 
			
		||||
                mJavaDetector = null;
 | 
			
		||||
            } else
 | 
			
		||||
                Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());
 | 
			
		||||
 | 
			
		||||
            mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);
 | 
			
		||||
 | 
			
		||||
            cascadeDir.delete();
 | 
			
		||||
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Log.i(TAG, "Instantiated new " + this.getClass());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void surfaceCreated(SurfaceHolder holder) {
 | 
			
		||||
        Log.i(TAG, "called surfaceCreated");
 | 
			
		||||
        synchronized (this) {
 | 
			
		||||
            // initialize Mats before usage
 | 
			
		||||
            mGray = new Mat();
 | 
			
		||||
            mRgba = new Mat();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        super.surfaceCreated(holder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Bitmap processFrame(VideoCapture capture) {
 | 
			
		||||
        capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
 | 
			
		||||
        capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
 | 
			
		||||
 | 
			
		||||
        if (mAbsoluteFaceSize == 0) {
 | 
			
		||||
            int height = mGray.rows();
 | 
			
		||||
            if (Math.round(height * mRelativeFaceSize) > 0) {
 | 
			
		||||
                mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
 | 
			
		||||
            }
 | 
			
		||||
            mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MatOfRect faces = new MatOfRect();
 | 
			
		||||
 | 
			
		||||
        if (mDetectorType == JAVA_DETECTOR) {
 | 
			
		||||
            if (mJavaDetector != null)
 | 
			
		||||
                mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
 | 
			
		||||
                        new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
 | 
			
		||||
        }
 | 
			
		||||
        else if (mDetectorType == NATIVE_DETECTOR) {
 | 
			
		||||
            if (mNativeDetector != null)
 | 
			
		||||
                mNativeDetector.detect(mGray, faces);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            Log.e(TAG, "Detection method is not selected!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rect[] facesArray = faces.toArray();
 | 
			
		||||
        for (int i = 0; i < facesArray.length; i++)
 | 
			
		||||
            Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
 | 
			
		||||
 | 
			
		||||
        Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
            if (mGray != null)
 | 
			
		||||
                mGray.release();
 | 
			
		||||
            if (mCascadeFile != null)
 | 
			
		||||
                mCascadeFile.delete();
 | 
			
		||||
            if (mNativeDetector != null)
 | 
			
		||||
                mNativeDetector.release();
 | 
			
		||||
 | 
			
		||||
            mRgba = null;
 | 
			
		||||
            mGray = null;
 | 
			
		||||
            mCascadeFile = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,123 +0,0 @@
 | 
			
		||||
package org.opencv.samples.fd;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    private FpsMeter            mFps;
 | 
			
		||||
 | 
			
		||||
    public SampleCvViewBase(Context context) {
 | 
			
		||||
        super(context);
 | 
			
		||||
        mHolder = getHolder();
 | 
			
		||||
        mHolder.addCallback(this);
 | 
			
		||||
        mFps = new FpsMeter();
 | 
			
		||||
        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");
 | 
			
		||||
        mFps.init();
 | 
			
		||||
 | 
			
		||||
        while (true) {
 | 
			
		||||
            Bitmap bmp = null;
 | 
			
		||||
 | 
			
		||||
            synchronized (this) {
 | 
			
		||||
                if (mCamera == null)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                if (!mCamera.grab()) {
 | 
			
		||||
                    Log.e(TAG, "mCamera.grab() failed");
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                bmp = processFrame(mCamera);
 | 
			
		||||
 | 
			
		||||
                mFps.measure();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
                    mFps.draw(canvas, (canvas.getWidth() - bmp.getWidth()) / 2, 0);
 | 
			
		||||
                    mHolder.unlockCanvasAndPost(canvas);
 | 
			
		||||
                }
 | 
			
		||||
                bmp.recycle();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Log.i(TAG, "Finished processing thread");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user