zoukankan      html  css  js  c++  java
  • Android应用开发提高篇(6)FaceDetector(人脸检测)

    一、概述

          初次看到FaceDetector这个类时,心里想:Android真的很强大。但直到我实际应用它的时候,心情从高山跌倒了谷底(看实现中的结果就知道了),再仔细看看官方文档,才知道这个类是API LEVEL1的,我就晕了,这就说明这个类很早就有了,但为什么到现在还没有得到改善呢。写这篇文章的目的还有一个,就是想强调一下用SurfaceView来画图的时候,要用某个事件来触发,而不能在程序一开始运行的时候就直接画图。好吧,下面看看这个类有多“强大”。


    二、实现

         新建工程MyFace,修改/res/layout/main.xml文件,在里面添加一个Button和一个SurfaceView,完整的main.xml如下:

     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:layout_width="fill_parent"
    4 android:layout_height="fill_parent"
    5 android:orientation="vertical" >
    6
    7 <Button
    8 android:id="@+id/button"
    9 android:layout_width="fill_parent"
    10 android:layout_height="wrap_content"
    11 android:text="开始检测"
    12 />
    13 <SurfaceView
    14 android:id="@+id/surfaceview"
    15 android:layout_width="fill_parent"
    16 android:layout_height="fill_parent"
    17
    18 />
    19
    20 </LinearLayout>

    修改MyFaceActivity.java文件,实现按钮的监听,在按钮被点击后实现画图和人脸检测,详细说明看代码注释:

      1 package com.nan.face;
    2
    3 import android.app.Activity;
    4 import android.graphics.Bitmap;
    5 import android.graphics.BitmapFactory;
    6 import android.graphics.Canvas;
    7 import android.graphics.Color;
    8 import android.graphics.Paint;
    9 import android.graphics.PointF;
    10 import android.graphics.Rect;
    11 import android.media.FaceDetector;
    12 import android.os.Bundle;
    13 import android.util.Log;
    14 import android.view.SurfaceHolder;
    15 import android.view.SurfaceView;
    16 import android.view.View;
    17 import android.widget.Button;
    18
    19 public class MyFaceActivity extends Activity
    20 {
    21 private Button mButton = null;
    22 private SurfaceView mSurfaceView = null;
    23 private SurfaceHolder mSurfaceHolder = null;
    24
    25 @Override
    26 public void onCreate(Bundle savedInstanceState)
    27 {
    28 super.onCreate(savedInstanceState);
    29 setContentView(R.layout.main);
    30
    31 mButton = (Button)findViewById(R.id.button);
    32 mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview);
    33 mSurfaceHolder = mSurfaceView.getHolder();
    34
    35 //按钮监听
    36 mButton.setOnClickListener(new View.OnClickListener()
    37 {
    38
    39 public void onClick(View v)
    40 {
    41 // TODO Auto-generated method stub
    42
    43 BitmapFactory.Options bitmapOption = new BitmapFactory.Options();
    44 //图片的参数(这个参数要有,不然找不到人脸)
    45 bitmapOption.inPreferredConfig = Bitmap.Config.RGB_565;
    46 Bitmap myBitmap;
    47 //获取图片资源
    48 myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mm,bitmapOption);
    49 //假设最多有5张脸
    50 int numOfFaces = 5;
    51 FaceDetector mFaceDetector = new FaceDetector(myBitmap.getWidth(),myBitmap.getHeight(),numOfFaces);
    52 FaceDetector.Face[] mFace = new FaceDetector.Face[numOfFaces];
    53 //获取实际上有多少张脸
    54 numOfFaces = mFaceDetector.findFaces(myBitmap, mFace);
    55 Log.v("------------->", ""+numOfFaces);
    56
    57 //锁定整个SurfaceView
    58 Canvas mCanvas = mSurfaceHolder.lockCanvas();
    59 //画图
    60 mCanvas.drawBitmap(myBitmap, 0f, 0f, null);
    61 //绘制完成,提交修改
    62 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
    63 //重新锁一次
    64 mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
    65 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
    66
    67 Paint mPaint = new Paint();
    68 //画笔颜色
    69 mPaint.setColor(Color.GREEN);
    70 //画笔的样式是矩形框,不是矩形块
    71 mPaint.setStyle(Paint.Style.STROKE);
    72 //线宽
    73 mPaint.setStrokeWidth(2.0f);
    74
    75 float eyesDistance = 0f;
    76
    77 //将所有检测到的脸框出来
    78 for(int i=0;i < numOfFaces;i++)
    79 {
    80 PointF eyeMidPoint = new PointF();
    81 //两眼的中点距离
    82 mFace[i].getMidPoint(eyeMidPoint);
    83 //两眼之间的距离
    84 eyesDistance = mFace[i].eyesDistance();
    85
    86 //锁定整个SurfaceView
    87 mCanvas = mSurfaceHolder.lockCanvas();
    88 //画矩形框
    89 mCanvas.drawRect((int)(eyeMidPoint.x-eyesDistance),
    90 (int)(eyeMidPoint.y-eyesDistance),
    91 (int)(eyeMidPoint.x+eyesDistance),
    92 (int)(eyeMidPoint.y+eyesDistance),
    93 mPaint);
    94 //绘制完成,提交修改
    95 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
    96 //重新锁一次
    97 mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
    98 mSurfaceHolder.unlockCanvasAndPost(mCanvas);
    99
    100 }
    101
    102 }
    103 });
    104 }
    105
    106 }

    好,运行这个程序看看:

    嗯,是检测出来了。等等,换一张有2张人脸的图片,再运行这个程序看看:

    嗯,也检测出来了,不过只检测出来一个。

          检测速度先不说了,不知道是我写的程序有问题,还是Android本身只能检测一个?希望是我的程序有问题。


    PS:所用的图片是网上找的。


  • 相关阅读:
    vuejs 实战 双向数据绑定
    ubuntu16安装cuda,cudnn,gpu版opencv
    ubuntu编译安装nginx并且配置流服务器
    安装使用mongodb
    c++ 编译安装ffmpeg
    apache2 日志文件太大的解决方案
    sql注入
    制作自己的电子词典
    python传递可变参数
    工厂模式
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2388776.html
Copyright © 2011-2022 走看看