Android中使用OpenCV检测人脸(Android studio版)

若openCV官网进不了,此处也可以下载OpenCV SDK http://blog.csdn.net/yanzi1225627/article/details/47668021


一、导入opencv sdk(java)

新建Module,导入eclipse项目

Android中使用OpenCV检测人脸(Android studio版)_第1张图片
路径选择为

opencv-3.3.0-android-sdk\OpenCV-android-sdk\sdk\java

名字可随意。
Android中使用OpenCV检测人脸(Android studio版)_第2张图片

导入之后调到能正常编译通过即可。

二、使用此SDK

1、可以把此module生成jar包使用。
2、也可以直接在其他module中引用此library module,方法如下:
Android中使用OpenCV检测人脸(Android studio版)_第3张图片
Android中使用OpenCV检测人脸(Android studio版)_第4张图片
即可成功引用。。。

三、上代码

1、在res目录下新建raw文件夹存放人脸模型文件,
人脸模型文件在下载的Opencv Sdk目录下:

opencv-3.3.0-android-sdk\OpenCV-android-sdk\sdk\etc\lbpcascades

Android中使用OpenCV检测人脸(Android studio版)_第5张图片

2、导.a 和 .so
把此位置中全部复制到项目 libs目录下:

opencv-3.3.0-android-sdk\OpenCV-android-sdk\sdk\native\libs
Android中使用OpenCV检测人脸(Android studio版)_第6张图片

在build.gradle中加入:
Android中使用OpenCV检测人脸(Android studio版)_第7张图片

sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }

即可成功引用.a和.so。

3、AndroidManifest.xml加入权限:

Android中使用OpenCV检测人脸(Android studio版)_第8张图片

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.front"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.front.autofocus"
        android:required="false" />

4、布局文件xml:(这里用opencv提供的JavaCameraView控件)


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <org.opencv.android.JavaCameraView
        android:id="@+id/javaCameraView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
LinearLayout>

5、activity中:

public class OpencvActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
    private CameraBridgeViewBase openCvCameraView;

    private static final String TAG = "OpencvActivity";
    private CascadeClassifier cascadeClassifier = null; //级联分类器
    private Mat mRgba; //图像容器
    private Mat mGray;
    private int absoluteFaceSize = 0;
    private Handler handler;

    private void initializeOpenCVDependencies() {
        try {
            InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface_improved); //OpenCV的人脸模型文件: lbpcascade_frontalface_improved
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            File mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface_improved.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();
            // 加载cascadeClassifier
            cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
        } catch (Exception e) {
            Log.e(TAG, "Error loading cascade", e);
        }
        // 显示
        openCvCameraView.enableView();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_opencv);

        new GetRunAuthorityUtil().getRunAuthority(this, this); //动态获取权限

        handler = new Handler();

        openCvCameraView = (CameraBridgeViewBase) findViewById(R.id.javaCameraView);
        openCvCameraView.setCameraIndex(0); //摄像头索引        -1/0:后置双摄     1:前置
        openCvCameraView.enableFpsMeter(); //显示FPS
        openCvCameraView.setCvCameraViewListener(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            Log.e(TAG, "OpenCV init error");
        }
        initializeOpenCVDependencies();
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat();
        mGray = new Mat();
    }

    @Override
    public void onCameraViewStopped() {
        mRgba.release();
        mGray.release();
    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba(); //RGBA
        mGray = inputFrame.gray(); //单通道灰度图

        if (absoluteFaceSize == 0) {
            int height = mGray.rows();
            if (Math.round(height * 0.2f) > 0) {
                absoluteFaceSize = Math.round(height * 0.2f);
            }
        }

        //解决  前置摄像头旋转显示问题
        //Core.flip(mRgba, mRgba, 1); //旋转
        //Core.flip(mGray, mGray, 1);

        //检测并显示
        MatOfRect faces = new MatOfRect();
        if (cascadeClassifier != null) {
            cascadeClassifier.detectMultiScale(mGray, faces, 1.1, 2, 2, new Size(absoluteFaceSize, absoluteFaceSize), new Size());
        }
       Rect[] facesArray = faces.toArray();
            if (facesArray.length > 0){
                for (int i = 0; i < facesArray.length; i++) {    //用框标记
                    Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
                }
            }
        return mRgba;
    }
}

另:这样可能会出现一个问题:启动后,屏幕画面是倒立的

解决:在AndroidManifest.xml中的activity设置横屏:
这里写图片描述

android:screenOrientation="landscape"

这样应该能成功了。
若有问题,欢迎大家前来讨论哦



最后下载的Opencv SDK中也有官方demo,位置在:

opencv-3.3.0-android-sdk\OpenCV-android-sdk\samples\face-detection

你可能感兴趣的:(Android)