Android应用开发提高篇(6)-----FaceDetector(人脸检测)

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/10/2388776.html

一、概述

初次看到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:所用的图片是网上找的。

时间: 2024-10-14 01:22:47

Android应用开发提高篇(6)-----FaceDetector(人脸检测)的相关文章

Android应用开发提高篇(1)-----获取本地IP

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/21/2361802.html 一.概述 习惯了Linux下的网络编程,在还没用智能机之前就一直想知道怎么得到手机的IP地址(玩智能机之前我是不搞手机应用的).好了,得知Android是基于Linux内核的,那么不就可以利用之前学的Linux下的网络编程方法来获取IP了吗?呵呵,其实这是比较底层的方法,在Android上,完全可以利用Java的API来实现,而且实现的代码非常简单.下面的实现只可

Android JNI开发提高篇

有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢? Android平台在中间层和大部分的类库的底层使用了C++的开发方式,后缀为.cpp,比如Android Framework.OpenCore.Webkit.SQLite等等.使用C++好处就是可以使用很多库但目前Android不支持STL,我们知道C表示字符串都是字

Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)(转载)

转自:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把它给完善了.加入了多线程,这样UI线程就不会被阻塞:实现了客户端和服务器的双向通信,只要客户端发起了连接并成功连接后那么两者就可以随意进行通信了. 二.实现 在之前的工程基础上进行修改就可以了. MyClient工程的main.xml文件不用修改,只需要修改MyClientActivity.java文件

Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/26/2368696.html 一.概述 TextToSpeech,就是将文本内容转换成语音,在其他的一些应用中经常可以看到.这个功能还是挺强大的,但是用户利用它来编写应用却很简单. 二.要求 能够将文本内容转换成语音并朗读出来:可以一次全部朗读出来,也可以边写边读:可以将文本保存为语音文件. 三.实现 新建工程MySpeak,修改/res/layout/main.xml文件,在里面添加一个Ed

Android应用开发提高篇(5)-----Camera使用

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html 一.概述 Camera是手机的一个很重要的设备,可以说现在的每一部手机上都有.回想当时在Linux搞摄像头编程真的要捏一把汗.有人会说在Linux下装个opencv就可以通过它的函数来使用摄像头啦,但我并没有这么做,我还是用最原始的方法(V4L2)实现了.之前研究过Android关于摄像头这部分的源码,毫无疑问,Android关于摄像头底层的实现用的也是V4L2.

Android应用开发进阶篇-场景文字识别

由于研究生毕业项目需要完成一个基于移动终端的场景文字识别系统,虽然离毕业尚早,但出于兴趣的缘故,近一段抽时间完成了这样一套系统.基本的架构如下: 客户端:Android应用实现拍摄场景图片,大致划出感兴趣文字区域,通过socket通信上传服务器端识别; 服务器端:Python server进行socket通信监听,连通后调用文字识别引擎(exe可执行程序),将识别结果返回; 下面是系统运行示例图: 1. 客户端 包含两个Activity,: MainActivity主界面如上图左1,选择拍摄后调

Android应用开发基础篇(12)-----Socket通信(转载)

转自:http://www.devdiv.com/android_socket_-blog-258060-10594.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得socket编程是网络编程的基础.在进入正题之前,先介 绍几点网络知识,一:socket编程有分TCP和UDP两种,TCP是基于连接的,而UDP是无连接的:二:一个TCP连接包括了输入和输出两条独立的 路径:三:服务器必须先运行然后客户端才能与它进行通信.四:客户端与服务

Android应用开发基础篇(12)-----Socket通信

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得socket编程是网络编程的基础.在进入正题之前,先介绍几点网络知识,一:socket编程有分TCP和UDP两种,TCP是基于连接的,而UDP是无连接的:二:一个TCP连接包括了输入和输出两条独立的路径:三:服务器必须先运行然后客户端才能与它进行通信.四:客户端与服

Android应用开发基础篇(3)-----ListView

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/16/2354625.html 一.概述 ListView是一个列表显示控件,它的应用非常广泛,在很多应用程序中都可以看到它的身影,比如来电通,网易新闻等等,特别是QQ.因此非常有必要熟练掌握它. 二.要求 能够利用ListView显示一些内容,如数据.文本,某一行被点击时有相应的提示:能够实现简单的ListView的动态插入和删除. 三.实现 新建工程MyListView,修改/res/lay