导读

OpenCV 是一个开源的跨平台计算机视觉库, 采C++语言编写,实现了图像处理和计算机视觉方面的很多通用算法,同时也提供对Python,Java,Android等的支持,这里利用Android下的接口,实现一个简单的人脸检测;

首先需要说清楚这里是人脸检测,不是人脸识别,网上很多资料说实现人脸识别,最后一看明明是人脸检测。

人脸检测:是找出人脸,并标记出人脸。

人脸识别:检测出人脸,并能够通过学习,给出人脸信息,比如,给定一个人脸A,通过学习,在之后的众多检测中能够找出人脸A,这才是人脸识别;

准备工作

首先到http://opencv.org/releases.html下载相应的开发工具,我下载时latest version是3.4.1,选择Android pack。开发包比较大,我下载时已经300多M。下载后解压缩,得到如下目录结构;



新建AS项目,OpenCVDemo,然后File > New > New Module,选择Import Eclipse ADT Project;

把下载下来的目录下sdk/java 下的项目导入到项目里。此时生产的Module名称为openCVLibrary2411,版本不同这里名字会不同,后面添加依赖时,需要注意!

然后将刚新建的这个modules 添加依赖到 app modules里,

直接在 app 目录下build.gradle 文件里dependencies 下添加:

  1. compile project(':openCVLibrary2411')

然后在 app/src/main 目录下创建一个jniLibs 目录,然后把sdk/native/libs 下全部文件 copy到jniLibs下,编译通过。

修改新建模块下 build.gradle 文件,把 compileSdkVersion 与 targetSdkVersion修改成你最新的SDK版本,如我的:

  1. apply plugin: 'com.android.library'
  2. android {
  3. compileSdkVersion 27
  4. buildToolsVersion "26.0.2"
  5. defaultConfig {
  6. minSdkVersion 21
  7. targetSdkVersion 27
  8. }
  9. buildTypes {
  10. release {
  11. minifyEnabled false
  12. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
  13. }
  14. }
  15. }

我app下的build.gradle文件如下:

  1. apply plugin: 'com.android.application'
  2. android {
  3. compileSdkVersion 27
  4. defaultConfig {
  5. applicationId "com.jiajia.opencvdemo"
  6. minSdkVersion 21
  7. targetSdkVersion 27
  8. versionCode 1
  9. versionName "1.0"
  10. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  11. }
  12. buildTypes {
  13. release {
  14. minifyEnabled false
  15. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  16. }
  17. }
  18. }
  19. dependencies {
  20. implementation fileTree(dir: 'libs', include: ['*.jar'])
  21. implementation 'com.android.support:appcompat-v7:27.1.1'
  22. implementation 'com.android.support.constraint:constraint-layout:1.1.0'
  23. testImplementation 'junit:junit:4.12'
  24. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  25. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  26. implementation project(':openCVLibrary2411')
  27. }

OK, 上面就是所有的准备工作;

实现人脸检测

只需要有一个MainActivity即可,首先申请相应的权限

  1. <uses-permission android:name="android.permission.CAMERA"/>
  2. <uses-feature android:name="android.hardware.camera" android:required="false"/>
  3. <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
  4. <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
  5. <uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

如果是Android是6.0以上,调用相机需要动态申请权限(小Demo,我直接在设置中为应用赋予了权限);

修改MainActivity代码如下:

  1. public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener{
  2. private CameraBridgeViewBase openCvCameraView;
  3. private CascadeClassifier cascadeClassifier;
  4. private Mat grayscaleImage;
  5. private int absoluteFaceSize;
  6. private void initializeOpenCVDependencies() {
  7. try {
  8. InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
  9. File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
  10. File mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
  11. FileOutputStream os = new FileOutputStream(mCascadeFile);
  12. byte[] buffer = new byte[4096];
  13. int bytesRead;
  14. while ((bytesRead = is.read(buffer)) != -1) {
  15. os.write(buffer, 0, bytesRead);
  16. }
  17. is.close();
  18. os.close();
  19. cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
  20. } catch (Exception e) {
  21. Log.e("OpenCVActivity", "Error loading cascade", e);
  22. }
  23. openCvCameraView.enableView();
  24. }
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  29. openCvCameraView = new JavaCameraView(this, -1); // 新建一个布局文件
  30. setContentView(openCvCameraView); // 为该活动设置布局
  31. openCvCameraView.setCvCameraViewListener(this);
  32. }
  33. @Override
  34. public void onCameraViewStarted(int width, int height) {
  35. grayscaleImage = new Mat(height, width, CvType.CV_8UC4);
  36. absoluteFaceSize = (int) (height * 0.2);
  37. }
  38. @Override
  39. public void onCameraViewStopped() {
  40. }
  41. @Override
  42. public Mat onCameraFrame(Mat aInputFrame) {
  43. Imgproc.cvtColor(aInputFrame, grayscaleImage, Imgproc.COLOR_RGBA2RGB);
  44. MatOfRect faces = new MatOfRect();
  45. if (cascadeClassifier != null) {
  46. cascadeClassifier.detectMultiScale(grayscaleImage, faces, 1.1, 2, 2,
  47. new Size(absoluteFaceSize, absoluteFaceSize), new Size());
  48. }
  49. Rect[] facesArray = faces.toArray();
  50. for (int i = 0; i <facesArray.length; i++)
  51. Core.rectangle(aInputFrame, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
  52. return aInputFrame;
  53. }
  54. @Override
  55. public void onResume() {
  56. super.onResume();
  57. if (!OpenCVLoader.initDebug()) {
  58. }
  59. initializeOpenCVDependencies();
  60. }
  61. }

简单分析:

首先onCreate方法中设置屏幕常亮.

  1. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

然后新建了一个布局openCvCameraView,这个布局文件是OpenCV封装好了,不需要我们重写布局文件,因为请看setContentView方法,这和平时我们写Activity是不一样的。

  1. openCvCameraView = new JavaCameraView(this, -1); // 新建一个布局文件
  2. setContentView(openCvCameraView); // 为该活动设置布局

然后为这个布局类设置了回调监听, 因为我们的MainActivity实现了CameraBridgeViewBase.CvCameraViewListener,所以监听器就是本身;

  1. openCvCameraView.setCvCameraViewListener(this);

实现了该监听器,就需要实现onCameraViewStarted onCameraViewStopped onCameraFrame这三个方法,具体实现的逻辑就在这三个方法中,涉及到很多数据知识,就不多说了(我也不是很懂!!!)

参考资料

  1. Android 接入 OpenCV库的三种方式

最后

  • 本文内容个人拙见,若有出入,欢迎指正。
  • 欢迎赏脸关注:家佳Talk

Android—基于OpenCV+Android实现人脸检测的更多相关文章

  1. OpenCV + python 实现人脸检测(基于照片和视频进行检测)

    OpenCV + python 实现人脸检测(基于照片和视频进行检测) Haar-like 通俗的来讲,就是作为人脸特征即可. Haar特征值反映了图像的灰度变化情况.例如:脸部的一些特征能由矩形特征 ...

  2. 基于Haar特征Adaboost人脸检测级联分类

    基于Haar特征Adaboost人脸检测级联分类 基于Haar特征Adaboost人脸检测级联分类,称haar分类器. 通过这个算法的名字,我们能够看到这个算法事实上包括了几个关键点:Haar特征.A ...

  3. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...

  4. OpenCV例程实现人脸检测

    前段时间看的OpenCV,其实有很多的例子程序,参考代码值得我们学习,对图像特征提取三大法宝:HOG特征,LBP特征,Haar特征有一定了解后. 对本文中的例子程序刚开始没有调通,今晚上调通了,试了试 ...

  5. OpenCV入门指南----人脸检测

    本篇介绍图像处理与模式识别中最热门的一个领域——人脸检测(人脸识别).人脸检测可以说是学术界的宠儿,在不少EI,SCI高级别论文都能看到它的身影.甚至很多高校学生的毕业设计都会涉及到人脸检测.当然人脸 ...

  6. 基于Opencv快速实现人脸识别(完整版)

    无耻收藏网页链接: 基于OpenCV快速实现人脸识别:https://blog.csdn.net/beyond9305/article/details/92844258 基于Opencv快速实现人脸识 ...

  7. Android 中使用 dlib+opencv 实现动态人脸检测

    1 概述 完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo.该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用 ...

  8. OpenCV神技——人脸检测,猫脸检测

    简介   OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 ...

  9. 手把手教你如何用 OpenCV + Python 实现人脸检测

    配好了OpenCV的Python环境,OpenCV的Python环境搭建.于是迫不及待的想体验一下opencv的人脸识别,如下文. 必备知识 Haar-like Haar-like百科释义.通俗的来讲 ...

随机推荐

  1. SQL、T-SQL与PL-SQL的区别

    SQL.T-SQL与PL-SQL的区别 SQL是Structrued Query Language的缩写,即结构化查询语言.它是负责与ANSI(美国国家标准学会)维护的数据库交互的标准.作为关系数据库 ...

  2. web常用软件

    编辑器: VSCode HBuilder WebStorm NotePad++ Eclipse Atom 常用插件: SwitchyOmega Vue-Tools server类: tomcat Ng ...

  3. Linux进程间通信---管道和有名管道

    一.管道 管道:管道是一种半双工的通信方式,数据只能单方向流动,而且只能在具有亲缘关系的进程间使用,因为管道 传递数据的单向性,管道又称为半双工管道.进程的亲缘关系通常是指父子进程关系. 管道的特点决 ...

  4. EF core 中用lambda表达式和Linq的一些区别

    转眼一看,又过了10几天没有写博客了,主要还是没有什么可以写的,因为遇到的问题都不是很有价值.不过最近发现用lambda表达式,比用Linq的代码量会少一些,而且也方便一些.不过两者都差不多,相差不是 ...

  5. java 读取图片并转化为二进制字符串

    本例子的目的在于测试往oracle数据库中插入blob字段 //以下代码源于:https://www.cnblogs.com/ywlx/p/4544179.html public static Str ...

  6. 使用公共的存储过程实现repeater的分页

    当一个项目repeater分页多的时候使用公共的存储过程实现分页,是不错的选择 ALTER PROC [dbo].[P_Common_proc] -- 通用分页存储过程 @TableName varc ...

  7. python实现归并排序,归并排序的详细分析

    python实现归并排序,归并排序的详细分析.   学习归并排序的过程是十分痛苦的.它并不常用,看起来时间复杂度好像是几种排序中最低的,比快排的时间复杂度还要低,但是它的执行速度不是最快的.很多朋友不 ...

  8. 进一步理解 frame 和 bounds

    总结一下 iOS中 frame 和 bounds之间的区别    综述 frame和bounds都是描述一块矩形区域,但是他们是有区别的 frame:可视范围,可以理解为控件的大小,把控件当作边缘很薄 ...

  9. python装饰器+递归+冒泡排序

    冒泡排序 li = [33, 2, 10, 1,23,23523,5123,4123,1,2,0] for k in range(1,len(li)): for i in range(len(li) ...

  10. ruby URI类

    一. URI require 'uri' uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413") # ...