as中opencv的使用 人脸检测
2017-06-21 14:52
239 查看
做一个预研 开始学习下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_fronta 12e60 lface.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);//后置摄像头}}@Overridepublic void onCameraViewStarted(int width, int height) {matLin = new Mat(height, width, CvType.CV_8UC4);//临时图像// 人脸小于高度的百分之30就不检测absoluteFaceSize = (int) (height * 0.3);}@Overridepublic void onCameraViewStopped() {}@Overridepublic 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 facesif (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-featureandroid:name="android.hardware.camera"android:required="false" /><uses-featureandroid:name="android.hardware.camera.autofocus"android:required="false" /><uses-featureandroid:name="android.hardware.camera.front"android:required="false" /><uses-featureandroid:name="android.hardware.camera.front.autofocus"android:required="false" />
6.0以上的动态权限就不加了 手动去权限管理里面开一下就行了
这里一直遇到启动了摄像头 黑屏问题 最后发现是出图像翻转处理的问题 加了注释 但是在手机上实测 横屏方向正常 在竖屏时图像左转了90度 很蛋疼 不过总算出来了
先这样吧 检测出来了 识别是否一致 继续研究
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- 使用OpenCV Android SDK从摄像头帧实时检测人脸
- Android中使用OpenCV检测人脸(Android studio版)
- 结合OpenCV摄像头使用Dlib库进行人脸检测及标注特征点和提取人脸特征-Python
- python中使用OpenCV进行人脸检测的例子
- Android使用OpenCV实现「人脸检测」和「人脸识别」
- opencv人脸检测实现(使用MFC做可视化)(一)
- Java使用OpenCV实现人脸识别/人眼检测/图片截取/合成/添加水印
- OpenCV人脸检测使用detectMultiScale可能会报错_CrtIsValidHeapPointer的解决方法
- 使用OpenCV进行人脸检测(Viola-Jones人脸检测方法)
- Android使用OpenCV实现「人脸检测」和「人脸识别」
- OpenCVForUnity使用Haar分类器检测人脸和眼睛
- OpenCV 人脸检测自学(5)_如何使用opencv_traincascade
- Java使用OpenCV人脸检测
- AdaBoost 人脸检测介绍(6) : 使用OpenCV自带的 AdaBoost程序训练并检测目标
- OpenCV学习笔记(一):使用CascadeClassifier检测人脸
- 使用OpenCV调用摄像头检测人脸并截图-Python
- 使用OpenCV实现人脸的实时检测与追踪
- OpenCV4Android开发实录(2): 使用OpenCV3.4.1库实现人脸检测
- 使用python-opencv人脸检测,画框,添加字符函数