openCV 人脸检测在 Android 中的应用

前言

上篇文章介绍了 Android 的人脸检测,这篇文章来介绍 openCV 的人脸检测。由于在 Android 平台上能直接使用 JavaCV,而 JavaCV 包含 openCV。所以,这篇文章就在 JavaCV 的基础上来实现 openCV 的人脸检测。

引入 JavaCV

下载 JavaCV 需要的包

下载地址
需要下载的包:javacv-bin.zip 和 opencv-2.4.3-android-arm.zip

引用 JavaCV

分别解压下载的包。将 javacv-bin 中的 javacpp.jar 和 javacv.jar 拷贝到项目的 libs 下,并引用。

将 opencv-2.4.3-android-arm 中 libs 下的 armeabi 和 armeabi-v7a 中的 .so 文件拷贝到项目的 libs 下的 armeabi 和 armeabi-v7a 中。

人脸检测

加载分类器

    public void init() throws IOException {
      File classifierFile  = Loader.extractResource(getClass(),
          "/com/ifenghui/face/camera/haarcascade_frontalface_alt2.xml", getCacheDir(), "classifier",
          ".xml");//获取分类器文件
      if (classifierFile == null || classifierFile.length() <= 0) {
        throw new IOException("Could not extract the classifier file from Java resource.");
      }

      // Preload the opencv_objdetect module to work around a known bug.
      Loader.load(opencv_objdetect.class);//加载分类器
      classifier =
        new opencv_objdetect.CvHaarClassifierCascade(cvLoad(classifierFile.getAbsolutePath()));//获取分类器对象
      classifierFile.delete();
      if (classifier.isNull()) {
        throw new IOException("Could not load the classifier file.");
      }
      storage = opencv_core.CvMemStorage.create();
    }

注:第 2,3,4 行中使用的分类器文件 haarcascade_frontalface_alt2.xml 在 openCV 安装路径下的 data/haarcascades/ 下。

人脸检测

    protected void detectorFaceFromImage(Bitmap faceBitmap, int width, int height) {
      // First, downsample our image and convert it into a grayscale IplImage
      int f = SUBSAMPLING_FACTOR;//图片缩小倍数
      if (grayImage == null || grayImage.width() != width / f || grayImage.height() != height / f) {
        grayImage = opencv_core.IplImage.create(width / f, height / f, opencv_core.IPL_DEPTH_8U,
          1);//创建缩小后的 IplImage
      }

      opencv_core.IplImage faceIplImage = opencv_core.IplImage.create(width, height, IPL_DEPTH_8U, 4);
      faceBitmap.copyPixelsToBuffer(faceIplImage.getByteBuffer());//bitmap 转成 IplImage

      opencv_core.IplImage bitGray = opencv_core.IplImage.create(width, height, IPL_DEPTH_8U, 1);
      opencv_imgproc.cvCvtColor(faceIplImage, bitGray, opencv_imgproc.CV_BGR2GRAY);// 转换成灰度图片

      opencv_imgproc.cvResize(bitGray, grayImage, opencv_imgproc.CV_INTER_LINEAR);
      opencv_imgproc.cvEqualizeHist(grayImage, grayImage);//直方图均衡化,不知道干啥用的

      cvClearMemStorage(storage);
      facesCV = cvHaarDetectObjects(grayImage, classifier, storage, 1.1, 2,
        opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING);//调用人脸检测
      RectF rectF = new RectF();
      float scaleX = SUBSAMPLING_FACTOR;
      float scaleY = SUBSAMPLING_FACTOR;
      int total = facesCV.total();
      for (int i = 0; i < total; i++) {//获取人脸范围的矩形,一便绘制
        opencv_core.CvRect r = new opencv_core.CvRect(cvGetSeqElem(facesCV, i));
        int x = r.x(), y = r.y(), w = r.width(), h = r.height();
        rectF.set(x * scaleX, y * scaleY, (x + w) * scaleX, (y + h) * scaleY);
        //canvas.drawRect(x*scaleX, y*scaleY, (x+w)*scaleX, (y+h)*scaleY, paint);
      }
    }

结语

openCV 的人脸检测的效率很高,但是需要先加载分类器,这会影响检测的效率。如果需要检测的图片很少,加载分类器使用的时间所占的比重就大。在需要检测的图片不是太多的情况下使用 Android 的人脸检测似乎比 openCV 更好一些。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值