as中opencv的使用 人脸检测

做一个预研 开始学习下opencv的使用 先从导入项目开始


1、下载

进入官网(http://opencv.org/)下载OpenCV4Android并解压。目录结构如下图所示。

我下载了 opencv-3.2.0-android-sdk。zip



其中,sdk目录即是我们开发opencv所需要的类库;samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行android下的opencv开发提供参考


2、将OpenCV引入Android Studio

创建一个新项目  在Android Studio中选择File->Import Module,找到OpenCV解压的路径,选择sdk/java文件夹。

或者


看见 出来


3、更新build.gradle信息  选择 opencv里面的build。gradle 把

compileSdkVersion 25
buildToolsVersion "25.0.3"

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 25
}

信息改成和版本一致的

点击 open Module Settings


把 openlib 加到app的项目依赖里面


复制libs文件夹到项目中

在OpenCV的解压包中,将sdk-->native-->libs文件夹复制,粘贴在Project视图下app-->src-->main目录下,并将其重命名为jniLibs。


就可以了 

直接网上找段代码 看看可以使用不

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RelativeLayout;

import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.JavaCameraView;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
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.objdetect.CascadeClassifier;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity
        implements CameraBridgeViewBase.CvCameraViewListener {

    private CameraBridgeViewBase openCvCameraView;
    private CascadeClassifier cascadeClassifier;
    //图像人脸小于高度的多少就不检测
    private int absoluteFaceSize;
    //临时图像对象
    private Mat matLin;
    //最终图像对象
    private Mat mat;

    //前置摄像头
    public static int CAMERA_FRONT = 0;
    //后置摄像头
    public static int CAMERA_BACK = 1;

    private int camera_scene = CAMERA_BACK;

    private void initializeOpenCVDependencies() {
        try {
            // Copy the resource into a temp file so OpenCV can load it
            InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            File 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();


            // 加载人脸特征文件
            cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
        } catch (Exception e) {
            Log.e("OpenCVActivity", "Error loading cascade", e);
        }


        // And we are ready to go
        openCvCameraView.enableView();
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().clearFlags(
                WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);// 设置横屏模式以及全屏模式
        setContentView(R.layout.activity_main);

        final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relative);

        openCvCameraView = new JavaCameraView(this, CameraBridgeViewBase.CAMERA_ID_FRONT);
        openCvCameraView.setCvCameraViewListener(this);



  
  
 final Button button = new Button(MainActivity.this);         button.setText("切换摄像头");         button.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 if (camera_scene == CAMERA_FRONT) {//如果是前置摄像头就切换成后置
                    relativeLayout.removeAllViews();                     openCvCameraView.disableView();                     openCvCameraView = null;                     cascadeClassifier = null;
                    openCvCameraView = new JavaCameraView(MainActivity.this, CameraBridgeViewBase.CAMERA_ID_BACK);                     openCvCameraView.setCvCameraViewListener(MainActivity.this);
                    openCvCameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK);//后置摄像头                     camera_scene = CAMERA_BACK;
                    relativeLayout.addView(openCvCameraView);                     relativeLayout.addView(button);
                    initializeOpenCVDependencies();                 } else {
                    relativeLayout.removeAllViews();                     openCvCameraView.disableView();                     openCvCameraView = null;                     cascadeClassifier = null;
                    openCvCameraView = new JavaCameraView(MainActivity.this, CameraBridgeViewBase.CAMERA_ID_FRONT);                     openCvCameraView.setCvCameraViewListener(MainActivity.this);
                    openCvCameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT);//前置摄像头                     camera_scene = CAMERA_FRONT;
                    relativeLayout.addView(openCvCameraView);                     relativeLayout.addView(button);
                    initializeOpenCVDependencies();                 }             }         });
        relativeLayout.addView(openCvCameraView);         relativeLayout.addView(button);
if (camera_scene == CAMERA_FRONT ) { openCvCameraView .setCameraIndex ( CameraBridgeViewBase . CAMERA_ID_FRONT ) ; // 前置摄像头 } else if (camera_scene == CAMERA_BACK ) { openCvCameraView .setCameraIndex ( CameraBridgeViewBase . CAMERA_ID_BACK ) ; // 后置摄像头 } } @Override public void onCameraViewStarted ( int width , int height ) { matLin = new Mat ( height , width , CvType . CV_8UC4 ) ; // 临时图像 // 人脸小于高度的百分之 30 就不检测 absoluteFaceSize = ( int ) ( height * 0.3 ) ; } @Override public void onCameraViewStopped () { } @Override public Mat onCameraFrame ( Mat aInputFrame ) { // 转置函数 , 将图像翻转(顺时针 90 度) Core .transpose ( aInputFrame , matLin ) ; // 在手机横屏时方向正常 在竖屏时图片向左转了 90 度 小米手机 if (camera_scene == CAMERA_FRONT ) { // 前置摄像头 // // 转置函数 , 将图像翻转(对换) // Core.flip(matLin, aInputFrame, 1); 这个方法有问题 参数位置前后不一样 导致黑屏 // // 转置函数 , 将图像反转(对换 修改 0 1 )横屏方向正常 竖屏左转了 90 Core .flip ( aInputFrame , matLin , 1 ) ; mat = matLin ; } else if (camera_scene == CAMERA_BACK ) { // 后置摄像头 // 转置函数 , 将图像翻转(对换) // Core.flip(matLin, aInputFrame, 1); mat = aInputFrame ; } MatOfRect faces = new MatOfRect () ; Log .i ( "123456" , "absoluteFaceSize = " + absoluteFaceSize ) ; // Use the classifier to detect faces if (cascadeClassifier != null ) { cascadeClassifier .detectMultiScale (mat , faces , 1.1 , 1 , 1 , new Size (absoluteFaceSize , absoluteFaceSize ) , new Size ()) ; } // 检测出多少个 Rect[] facesArray = faces.toArray(); for (int i = 0; i < facesArray.length; i++) { Log.i("123456", "facesArray[i].tl() 坐上坐标 == " + facesArray[i].tl() + " facesArray[i].br() == 右下坐标 " + facesArray[i].br());
//3.2的sdk把core进行了拆分 细化 有的方法在别的类中 // Core.rectangle(mat, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
	//根据坐标绘制了一个方框
	Imgproc.rectangle(mat, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
} return mat ; } @Override public void onResume () { super.onResume () ; if ( ! OpenCVLoader .initDebug ()) { Log .e ( "log_wons" , "OpenCV init error" ) ; // Handle initialization error } initializeOpenCVDependencies () ; //OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback); } }


布局放一个id为relative全屏的空的RelativeLayout 就可以了
AndroidManifest中加上

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

<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" />


6.0以上的动态权限就不加了 手动去权限管理里面开一下就行了 
这里一直遇到启动了摄像头 黑屏问题 最后发现是出图像翻转处理的问题 加了注释  但是在手机上实测 横屏方向正常 在竖屏时图像左转了90度 很蛋疼 不过总算出来了  
先这样吧 检测出来了    识别是否一致 继续研究 




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值