C++ 代码

多种手机平台开发-----让我们跟苹果一起红起来。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Android API教程:人脸检测(Face Detect)

Posted on 2012-06-25 11:50  蔡清华  阅读(712)  评论(0编辑  收藏  举报

构建一个人脸检测的Android Activity

你可以构建一个通用的Android Activity,我们扩展了基类ImageView,成为MyImageView,而我们需要进行检测的包含人脸的位图文件必须是565格式,API才能正常工作。被检测出来的人脸需要一个置信测度(confidence measure),这个措施定义在android.media.FaceDetector.Face.CONFIDENCE_THRESHOLD。

最重要的方法实现在setFace(),它将FaceDetector对象实例化,同时调用findFaces,结果存放在faces里,人脸的中点转移到MyImageView。代码如下:

  1. public class TutorialOnFaceDetect1 extends Activity { 
  2.  private MyImageView mIV; 
  3.  private Bitmap mFaceBitmap; 
  4.  private int mFaceWidth = 200
  5.  private int mFaceHeight = 200
  6.  private static final int MAX_FACES = 1
  7.  private static String TAG = "TutorialOnFaceDetect"
  8.  
  9. @Override 
  10. public void onCreate(Bundle savedInstanceState) { 
  11. super.onCreate(savedInstanceState); 
  12.  
  13. mIV = new MyImageView(this); 
  14. setContentView(mIV, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
  15.  
  16. // load the photo 
  17. Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.face3); 
  18. mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true); 
  19. b.recycle(); 
  20.  
  21. mFaceWidth = mFaceBitmap.getWidth(); 
  22. mFaceHeight = mFaceBitmap.getHeight(); 
  23. mIV.setImageBitmap(mFaceBitmap); 
  24.  
  25. // perform face detection and set the feature points setFace(); 
  26.  
  27. mIV.invalidate(); 
  28.  
  29. public void setFace() { 
  30. FaceDetector fd; 
  31. FaceDetector.Face [] faces = new FaceDetector.Face[MAX_FACES]; 
  32. PointF midpoint = new PointF(); 
  33. int [] fpx = null
  34. int [] fpy = null
  35. int count = 0
  36.  
  37. try { 
  38. fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES); 
  39. count = fd.findFaces(mFaceBitmap, faces); 
  40. catch (Exception e) { 
  41. Log.e(TAG, "setFace(): " + e.toString()); 
  42. return
  43.  
  44. // check if we detect any faces 
  45. if (count > 0) { 
  46. fpx = new int[count]; 
  47. fpy = new int[count]; 
  48.  
  49. for (int i = 0; i < count; i++) { 
  50. try { 
  51. faces[i].getMidPoint(midpoint); 
  52.  
  53. fpx[i] = (int)midpoint.x; 
  54. fpy[i] = (int)midpoint.y; 
  55. catch (Exception e) { 
  56. Log.e(TAG, "setFace(): face " + i + ": " + e.toString()); 
  57.  
  58. mIV.setDisplayPoints(fpx, fpy, count, 0); 

接下来的代码中,我们在MyImageView中添加setDisplayPoints() ,用来在被检测出的人脸上标记渲染。图1展示了一个标记在被检测处的人脸上处于中心位置。

  1. // set up detected face features for display 
  2. public void setDisplayPoints(int [] xx, int [] yy, int total, int style) { 
  3.  mDisplayStyle = style; 
  4.  mPX = null
  5.  mPY = null
  6.  
  7. if (xx != null && yy != null && total > 0) { 
  8. mPX = new int[total]; 
  9. mPY = new int[total]; 
  10.  
  11. for (int i = 0; i < total; i++) { 
  12. mPX[i] = xx[i]; 
  13. mPY[i] = yy[i]; 
  14. 多人脸检测

    通过FaceDetector可以设定检测到人脸数目的上限。比如设置最多只检测10张脸:

    1. private static final int MAX_FACES = 10
    2. 定位眼睛中心位置

      Android人脸检测返回其他有用的信息,例同时会返回如eyesDistance,pose,以及confidence。我们可以通过eyesDistance来定位眼睛的中心位置。

      下面的代码中,我们将setFace()放在doLengthyCalc()中。同时图3展示了定位眼睛中心位置的效果。

      1. public class TutorialOnFaceDetect extends Activity { 
      2.  private MyImageView mIV; 
      3.  private Bitmap mFaceBitmap; 
      4.  private int mFaceWidth = 200
      5.  private int mFaceHeight = 200
      6.  private static final int MAX_FACES = 10
      7.  private static String TAG = "TutorialOnFaceDetect"
      8. private static boolean DEBUG = false
      9.  
      10. protected static final int GUIUPDATE_SETFACE = 999
      11. protected Handler mHandler = new Handler(){ 
      12. // @Override 
      13. public void handleMessage(Message msg) { 
      14. mIV.invalidate(); 
      15.  
      16. super.handleMessage(msg); 
      17. }; 
      18.  
      19. @Override 
      20. public void onCreate(Bundle savedInstanceState) { 
      21. super.onCreate(savedInstanceState); 
      22.  
      23. mIV = new MyImageView(this); 
      24. setContentView(mIV, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
      25.  
      26. // load the photo 
      27. Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.face3); 
      28. mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true); 
      29. b.recycle(); 
      30.  
      31. mFaceWidth = mFaceBitmap.getWidth(); 
      32. mFaceHeight = mFaceBitmap.getHeight(); 
      33. mIV.setImageBitmap(mFaceBitmap); 
      34. mIV.invalidate(); 
      35.  
      36. // perform face detection in setFace() in a background thread 
      37. doLengthyCalc(); 
      38.  
      39. public void setFace() { 
      40. FaceDetector fd; 
      41. FaceDetector.Face [] faces = new FaceDetector.Face[MAX_FACES]; 
      42. PointF eyescenter = new PointF(); 
      43. float eyesdist = 0.0f; 
      44. int [] fpx = null
      45. int [] fpy = null
      46. int count = 0
      47.  
      48. try { 
      49. fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES); 
      50. count = fd.findFaces(mFaceBitmap, faces); 
      51. catch (Exception e) { 
      52. Log.e(TAG, "setFace(): " + e.toString()); 
      53. return
      54.  
      55. // check if we detect any faces 
      56. if (count > 0) { 
      57. fpx = new int[count * 2]; 
      58. fpy = new int[count * 2]; 
      59.  
      60. for (int i = 0; i < count; i++) { 
      61. try { 
      62. faces[i].getMidPoint(eyescenter); 
      63. eyesdist = faces[i].eyesDistance(); 
      64.  
      65. // set up left eye location 
      66. fpx[2 * i] = (int)(eyescenter.x - eyesdist / 2); 
      67. fpy[2 * i] = (int)eyescenter.y; 
      68.  
      69. // set up right eye location 
      70. fpx[2 * i + 1] = (int)(eyescenter.x + eyesdist / 2); 
      71. fpy[2 * i + 1] = (int)eyescenter.y; 
      72.  
      73. if (DEBUG) { 
      74. Log.e(TAG, "setFace(): face " + i + ": confidence = " + faces[i].confidence() 
      75. ", eyes distance = " + faces[i].eyesDistance() 
      76. ", pose = ("+ faces[i].pose(FaceDetector.Face.EULER_X) + "," 
      77. + faces[i].pose(FaceDetector.Face.EULER_Y) + "," 
      78. + faces[i].pose(FaceDetector.Face.EULER_Z) + ")" 
      79. ", eyes midpoint = (" + eyescenter.x + "," + eyescenter.y +")"); 
      80. catch (Exception e) { 
      81. Log.e(TAG, "setFace(): face " + i + ": " + e.toString()); 
      82.  
      83. mIV.setDisplayPoints(fpx, fpy, count * 21); 
      84.  
      85. private void doLengthyCalc() { 
      86. Thread t = new Thread() { 
      87. Message m = new Message(); 
      88.  
      89. public void run() { 
      90. try { 
      91. setFace(); 
      92. m.what = TutorialOnFaceDetect.GUIUPDATE_SETFACE; 
      93. TutorialOnFaceDetect.this.mHandler.sendMessage(m); 
      94. catch (Exception e) { 
      95. Log.e(TAG, "doLengthyCalc(): " + e.toString()); 
      96. }; 
      97.  
      98. t.start();