Android使用OpenCV实现「人脸检测」和「人脸识别」

Android使用OpenCV实现「人脸检测」和「人脸识别」

DEMO

OpenCV+JavaCV实现人脸识别

—————————-分割线———————————

效果图

先上效果图,不好弄gif

CV1

CV2

CV3

CV4

在网上找了在Android平台上使用OpenCV相关的教程,很少,大部分也都主要是介绍下人脸检测,很少有讲人脸识别,还有的人连人脸检测和人脸识别的概念都没有搞清,人脸检测只是识别到有人脸,能获取到一个人脸的大概位置,有几个人脸,而人脸识别是要获取到人脸特征做对比,识别这个人脸。有好多文章都写自己在讲人脸识别,实际上他只是做了人脸检测。

OpenCV官网

官方给的Demo是在Eclipse工程下的,如果你现在已经是在Android Studio下开发,因为Eclipse工程有makefile文件,迁移到Android Studio好像还是有点麻烦,我是干脆就在Eclipse下跑的Demo。

先甩过来官方给的一些文档:

OpenCV4Android SDK

Android Development with OpenCV

实现方式

按照官方的文档,我们在Eclipse里导入Demo进去以后,是不能直接运行的,需要安装Manager的一个APK,然后在Demo工程里通过AIDL的方式,调用OpenCV的核心方法,不过Demo给实现的功能也只是一个人脸检测。

SDK

SDK下载

下面来看一下SDK

P1

目录:

  • apk:Manager的apk
  • doc:一些文档
  • samples:示例工程和一些编译好的apk
  • sdk:一些库文件

当然, 如果你的C/C++足够好,你肯定可以自己编译一个库,直接导入到工程,就不用安装Manager了,可惜了我自己还不行,哈哈……无奈安装Manager把……

如何将Demo导入到Eclipse并运行,上面官方的文档已经说的比较清楚了,至于会有什么问题就自行Google吧。

人脸检测

其实人脸检测并不是重点,Demo里已经实现了人脸检测的功能。

主要的实现方式:OpenCV有一个自己的org.opencv.android.JavaCameraView自定义控件,它循环的从摄像头抓取数据,在回调方法中,我们能获取到Mat数据,然后通过调用OpenCV的Native方法,检测当前是否有人脸,我们会获取到一个Rect数组,里面会有人脸数据,最后将人脸画在屏幕上,到此为止,Demo的人脸检测功能,就结束了。

人脸识别

人脸识别我这里用到了JavaCV

P2

人脸识别逻辑:人脸识别的主要方式就是获取到人脸的特征值,然后将两个特征值做比对,取到一个相似度去做人脸识别,OpenCV这里的特征值,其实就是一张图片。
我们的从回调的Mat数据检测到有人脸以后,提取特征值(也就是保存人脸的一张图片到某个路径),然后比较特征值

为了提高识别的准确度,需要在检测到人脸以后,把人脸的部分截取出来,然后置灰(置灰的目的是为了方式色泽和明暗度对识别有影响)。

保存人脸特征值

/**
 * 特征保存
 *
 * @param image    Mat
 * @param rect     人脸信息
 * @param fileName 文件名字
 * @return 保存是否成功
 */
public boolean saveImage(Mat image, Rect rect, String fileName) {
    try {
        String PATH = Environment.getExternalStorageDirectory() + "/FaceDetect/" + fileName + ".jpg";
        // 把检测到的人脸重新定义大小后保存成文件
        Mat sub = image.submat(rect);
        Mat mat = new Mat();
        Size size = new Size(100, 100);
        Imgproc.resize(sub, mat, size);
        Highgui.imwrite(PATH, mat);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

提取特征值

之前已经说了嘛,人脸特征其实就是一张人脸图片,所以提取人脸特征其实就是获取一张人脸图片

/**
 * 提取特征
 *
 * @param fileName 文件名
 * @return 特征图片
 */
public Bitmap getImage(String fileName) {
    try {
        return BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/FaceDetect/" + fileName + ".jpg");
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

人脸识别

这里主要使用了JavaCV的方法

/**
 * 特征对比
 *
 * @param file1 人脸特征
 * @param file2 人脸特征
 * @return 相似度
 */
public double CmpPic(String file1, String file2) {
    int l_bins = 20;
    int hist_size[] = {l_bins};

    float v_ranges[] = {0, 100};
    float ranges[][] = {v_ranges};

    opencv_core.IplImage Image1 = cvLoadImage(Environment.getExternalStorageDirectory() + "/FaceDetect/" + file1 + ".jpg", CV_LOAD_IMAGE_GRAYSCALE);
    opencv_core.IplImage Image2 = cvLoadImage(Environment.getExternalStorageDirectory() + "/FaceDetect/" + file2 + ".jpg", CV_LOAD_IMAGE_GRAYSCALE);

    opencv_core.IplImage imageArr1[] = {Image1};
    opencv_core.IplImage imageArr2[] = {Image2};

    opencv_imgproc.CvHistogram Histogram1 = opencv_imgproc.CvHistogram.create(1, hist_size, CV_HIST_ARRAY, ranges, 1);
    opencv_imgproc.CvHistogram Histogram2 = opencv_imgproc.CvHistogram.create(1, hist_size, CV_HIST_ARRAY, ranges, 1);

    cvCalcHist(imageArr1, Histogram1, 0, null);
    cvCalcHist(imageArr2, Histogram2, 0, null);

    cvNormalizeHist(Histogram1, 100.0);
    cvNormalizeHist(Histogram2, 100.0);

    return cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL);
}

最后

看我轻描淡写了一篇博客写完了,看上去好像挺容易的,但是对于第一次做人脸识别的人或者对JNI还不是很熟的人来说,可能并没有想象的那么简单,你会遇到各种库找不到,编译不通过等等的问题,总之吧,一个大概的实现思路呈现出来,仅供参考,就是这样!

优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/454582

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。