I. Overview
When I first saw the facedetector class, I thought: Android is really powerful. However, when I applied it in practice, I fell down from the bottom of the mountain (I knew the result of the implementation), and then I checked the official documentation carefully to know that this class is API level1, I am dizzy, which indicates that this class has been available for a long time, But why hasn't it been improved yet. Another purpose of writing this article is to emphasize that when surfaceview is used for drawing, a certain event is used for triggering, rather than drawing directly when the program starts running. Well, let's see how powerful this class is ".
II. Implementation
Create a project myface, modify the/RES/layout/Main. xml file, and add a button and a surfaceview. The complete main. xml file is as follows:
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 = "Start detection"
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>
Modify the myfaceactivity. Java file to implement button listening. After the button is clicked, the image and face detection are implemented. For details, see the code comment:
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 // button listener
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 // Image Parameters (this parameter is required, or the face cannot be found)
45 bitmapoption. inpreferredconfig = bitmap. config. rgb_565;
46 bitmap mybitmap;
47 // obtain image resources
48 mybitmap = bitmapfactory. decoderesource (getresources (), R. drawable. Mm, bitmapoption );
49 // assume there are a maximum of five faces
50 int numoffaces = 5;
51 facedetector mfacedetector = new facedetector (mybitmap. getwidth (), mybitmap. getheight (), numoffaces );
52 facedetector. Face [] mface = new facedetector. Face [numoffaces];
53 // obtain the actual number of faces
54 numoffaces = mfacedetector. findfaces (mybitmap, mface );
55 log. V ("------------->", "" + numoffaces );
56
57 // lock the whole surfaceview
58 canvas mcanvas = msurfaceholder. lockcanvas ();
59 // drawing
60 mcanvas. drawbitmap (mybitmap, 0f, 0f, null );
61 // The painting is complete. Submit the modification.
62 msurfaceholder. unlockcanvasandpost (mcanvas );
63 // lock again
64 msurfaceholder. lockcanvas (New rect (0, 0, 0, 0 ));
65 msurfaceholder. unlockcanvasandpost (mcanvas );
66
67 paint mpaint = new paint ();
68 // paint brush color
69 mpaint. setcolor (color. Green );
70 // The pen style is a rectangle frame, not a rectangle Block
71 mpaint. setstyle (paint. style. Stroke );
72 // line width
73 mpaint. setstrokewidth (2.0f );
74
75 float eyesdistance = 0f;
76
77 // show all detected faces
78 for (INT I = 0; I <numoffaces; I ++)
79 {
80 pointf eyemidpoint = new pointf ();
81 // The midpoint distance between two eyes
82 mface [I]. getmidpoint (eyemidpoint );
83 // distance between two eyes
84 eyesdistance = mface [I]. eyesdistance ();
85
86 // lock the whole surfaceview
87 mcanvas = msurfaceholder. lockcanvas ();
88 // rectangular frame
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 // The painting is complete. Submit the modification.
95 msurfaceholder. unlockcanvasandpost (mcanvas );
96 // lock again
97 msurfaceholder. lockcanvas (New rect (0, 0, 0, 0 ));
98 msurfaceholder. unlockcanvasandpost (mcanvas );
99
100}
101
102}
103 });
104}
105
106}
Okay. Run this program to see:
Well, it was detected. Wait, change to an image with two faces, and then run this program to see:
Well, it was also detected, but only one was detected.
I don't know if there is a problem with the program I wrote, or can Android only detect one? I hope there is a problem with my program.
PS: The images used are found online.