ZhangXiangQian

 前段时间经理让做一个截取人脸部分的Demo,花了不少时间才算搞定,闲来无事,总结一下。

 android是通过检测两眼的位置来判断和获取人脸位置,两眼之间的距离和位置,通过API可以直接得到,代码如下:

  1 package org.yanzi.testfacedetect;
  2 
  3 import org.yanzi.util.DecodeBitmapUtils;
  4 import org.yanzi.util.ImageUtil;
  5 import org.yanzi.util.MyToast;
  6 
  7 import android.app.Activity;
  8 import android.content.Intent;
  9 import android.database.Cursor;
 10 import android.graphics.Bitmap;
 11 import android.graphics.Bitmap.Config;
 12 import android.graphics.BitmapFactory;
 13 import android.graphics.Canvas;
 14 import android.graphics.Color;
 15 import android.graphics.Paint;
 16 import android.graphics.Point;
 17 import android.graphics.PointF;
 18 import android.graphics.Rect;
 19 import android.media.FaceDetector;
 20 import android.media.FaceDetector.Face;
 21 import android.net.Uri;
 22 import android.os.Bundle;
 23 import android.os.Handler;
 24 import android.os.Message;
 25 import android.provider.MediaStore;
 26 import android.util.DisplayMetrics;
 27 import android.util.Log;
 28 import android.view.Menu;
 29 import android.view.View;
 30 import android.view.View.OnClickListener;
 31 import android.view.ViewGroup;
 32 import android.view.ViewGroup.LayoutParams;
 33 import android.widget.Button;
 34 import android.widget.ImageView;
 35 import android.widget.ProgressBar;
 36 import android.widget.RelativeLayout;
 37 import android.widget.Toast;
 38 
 39 public class MainActivity extends Activity {
 40     static final String tag = "yan";
 41     ImageView imgView = null;
 42     FaceDetector faceDetector = null;
 43     FaceDetector.Face[] face;
 44     Button detectFaceBtn = null, btn_startContent;
 45     final int N_MAX = 2;
 46     ProgressBar progressBar = null;
 47     private ImageView imgviewCrop;
 48 
 49     private String lastPicUri = null;
 50 
 51     Bitmap srcImg = null;
 52     Bitmap srcFace = null;
 53     Thread checkFaceThread = new Thread() {
 54 
 55         @Override
 56         public void run() {
 57             // TODO Auto-generated method stub
 58 
 59         }
 60 
 61     };
 62 
 63     class MyThread extends Thread {
 64         @Override
 65         public void run() {
 66             super.run();
 67             Bitmap faceBitmap = detectFace();
 68             if (faceBitmap == null) {
 69                 mainHandler.sendEmptyMessage(3);
 70                 return;
 71             }
 72             mainHandler.sendEmptyMessage(2);
 73             Message m = new Message();
 74             m.what = 0;
 75             m.obj = faceBitmap;
 76             mainHandler.sendMessage(m);
 77         }
 78     }
 79 
 80     Handler mainHandler = new Handler() {
 81 
 82         @Override
 83         public void handleMessage(Message msg) {
 84             // TODO Auto-generated method stub
 85             // super.handleMessage(msg);
 86             switch (msg.what) {
 87             case 0:
 88                 Bitmap b = (Bitmap) msg.obj;
 89                 // imgView.setImageBitmap(b);
 90                 imgviewCrop.setImageBitmap(b);
 91                 MyToast.showToast(getApplicationContext(), "检测完毕");
 92                 detectFaceBtn.setClickable(false);
 93                 break;
 94             case 1:
 95                 showProcessBar();
 96                 break;
 97             case 2:
 98                 progressBar.setVisibility(View.GONE);
 99                 // detectFaceBtn.setClickable(false);
100                 break;
101             case 3:
102                 Toast.makeText(MainActivity.this, "图片不符合要求,请重新选择",
103                         Toast.LENGTH_SHORT).show();
104                 progressBar.setVisibility(View.GONE);
105                 break;
106             default:
107                 break;
108             }
109         }
110 
111     };
112 
113     @Override
114     protected void onCreate(Bundle savedInstanceState) {
115         super.onCreate(savedInstanceState);
116         setContentView(R.layout.activity_main);
117         initUI();
118 
119         detectFaceBtn.setOnClickListener(new OnClickListener() {
120 
121             @Override
122             public void onClick(View v) {
123                 // TODO Auto-generated method stub
124                 mainHandler.sendEmptyMessage(1);
125                 new MyThread().start();
126             }
127         });
128 
129         btn_startContent = (Button) findViewById(R.id.btn_startContent);
130         btn_startContent.setOnClickListener(new OnClickListener() {
131 
132             @Override
133             public void onClick(View v) {
134                 Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
135                 getImage.addCategory(Intent.CATEGORY_OPENABLE);
136                 getImage.setType("image/jpeg");
137                 startActivityForResult(getImage, 0);
138             }
139         });
140 
141     }
142 
143     @Override
144     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
145         // TODO Auto-generated method stub
146         super.onActivityResult(requestCode, resultCode, data);
147 
148         if (data == null || resultCode != RESULT_OK) {
149             return;
150         }
151         String picture = getFilePath(data.getData());
152         if (picture == null) {
153 
154             Log.e(getClass().getName(), "目前只能取回相机里照片");
155             return;
156         }
157         showPhoto(imgView, picture);
158         detectFaceBtn.setClickable(true);
159     }
160 
161     /**
162      * 目前只能取回相机里照片
163      * 
164      * @param uri
165      * @return
166      */
167     private String getFilePath(Uri uri) {
168         String[] filePathColumn = { MediaStore.Images.Media.DATA };
169         Cursor cursor = getContentResolver().query(uri, filePathColumn, null,
170                 null, null);
171         if (cursor == null) {
172             return null;
173         }
174         cursor.moveToFirst();
175         int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
176         String picturePath = cursor.getString(columnIndex);
177         cursor.close();
178         return picturePath;
179     }
180 
181     public void showPhoto(ImageView photo, String picturePath) {
182         if ("".equals(picturePath))
183             return;
184         Bitmap bitmap = BitmapFactory.decodeByteArray(
185                 DecodeBitmapUtils.decodeBitmap(picturePath), 0,
186                 DecodeBitmapUtils.decodeBitmap(picturePath).length);
187         // photo.setImageDrawable(new BitmapDrawable(bitmap));
188         // photo.setSrcImage(bitmap);
189         photo.setImageBitmap(bitmap);
190         initSrcImg(bitmap);
191     }
192 
193     @Override
194     public boolean onCreateOptionsMenu(Menu menu) {
195         // Inflate the menu; this adds items to the action bar if it is present.
196         getMenuInflater().inflate(R.menu.main, menu);
197         return true;
198     }
199 
200     public void initUI() {
201 
202         detectFaceBtn = (Button) findViewById(R.id.btn_detect_face);
203         imgView = (ImageView) findViewById(R.id.imgview);
204         imgviewCrop = (ImageView) findViewById(R.id.imgviewCrop);
205 
206         initSrcImg(null);
207 
208     }
209 
210     private void initSrcImg(Bitmap bp) {
211         LayoutParams params = imgView.getLayoutParams();
212         DisplayMetrics dm = getResources().getDisplayMetrics();
213         int w_screen = dm.widthPixels;
214         // int h = dm.heightPixels;
215         if (bp == null) {
216             srcImg = BitmapFactory.decodeResource(getResources(),
217                     R.drawable.kunlong);
218         } else {
219             srcImg = bp;
220         }
221         initFaceDetect();
222 
223         int h = srcImg.getHeight();
224         int w = srcImg.getWidth();
225         float r = (float) h / (float) w;
226         params.width = w_screen;
227         params.height = (int) (params.width * r);
228         imgView.setLayoutParams(params);
229         imgView.setImageBitmap(srcImg);
230     }
231 
232     public void initFaceDetect() {
233         this.srcFace = srcImg.copy(Config.RGB_565, true);
234         int w = srcFace.getWidth();
235         int h = srcFace.getHeight();
236         Log.i(tag, "待检测图像: w = " + w + "h = " + h);
237         faceDetector = new FaceDetector(w, h, N_MAX);
238         face = new FaceDetector.Face[N_MAX];
239     }
240 
241     public boolean checkFace(Rect rect) {
242         int w = rect.width();
243         int h = rect.height();
244         int s = w * h;
245         Log.i(tag, "人脸 宽w = " + w + "高h = " + h + "人脸面积 s = " + s);
246         if (s < 10000) {
247             Log.i(tag, "无效人脸,舍弃.");
248             return false;
249         } else {
250             Log.i(tag, "有效人脸,保存.");
251             return true;
252         }
253     }
254 
255     public Bitmap detectFace() {
256         // Drawable d = getResources().getDrawable(R.drawable.face_2);
257         // Log.i(tag, "Drawable尺寸 w = " + d.getIntrinsicWidth() + "h = " +
258         // d.getIntrinsicHeight());
259         // BitmapDrawable bd = (BitmapDrawable)d;
260         // Bitmap srcFace = bd.getBitmap();
261 
262         int nFace = faceDetector.findFaces(srcFace, face);
263         Log.i(tag, "检测到人脸:n = " + nFace);
264         for (int i = 0; i < nFace; i++) {
265             Face f = face[i];
266             PointF midPoint = new PointF();
267             float dis = f.eyesDistance();
268             f.getMidPoint(midPoint);
269             int dd = (int) (dis);
270             Point eyeLeft = new Point((int) (midPoint.x - dis / 2),
271                     (int) midPoint.y);
272             Point eyeRight = new Point((int) (midPoint.x + dis / 2),
273                     (int) midPoint.y);
274             Rect faceRect = new Rect((int) (midPoint.x - dd),
275                     (int) (midPoint.y - dd), (int) (midPoint.x + dd),
276                     (int) (midPoint.y + dd));
277             Log.i(tag, "左眼坐标 x = " + eyeLeft.x + "y = " + eyeLeft.y);
278             if (checkFace(faceRect)) {
279                 Canvas canvas = new Canvas(srcFace);
280                 Paint p = new Paint();
281                 p.setAntiAlias(true);
282                 p.setStrokeWidth(8);
283                 p.setStyle(Paint.Style.STROKE);
284                 p.setColor(Color.GREEN);
285                 canvas.drawCircle(eyeLeft.x, eyeLeft.y, 20, p);
286                 canvas.drawCircle(eyeRight.x, eyeRight.y, 20, p);
287                 canvas.drawRect(faceRect, p);
288             }
289             if (i == 0) {
290                 int xLeft = (int) (midPoint.x - f.eyesDistance() * 2);
291                 int yLeft = (int) (midPoint.y - f.eyesDistance() * 2);
292                 Bitmap bitmap = Bitmap.createBitmap(srcImg, xLeft >= 0 ? xLeft
293                         : 0, yLeft >= 0 ? yLeft : 0,
294                         (int) f.eyesDistance() * 4, (int) f.eyesDistance() * 4,
295                         null, true);
296                 return bitmap;
297             }
298         }
299 
300         ImageUtil.saveJpeg(srcFace);
301         Log.i(tag, "保存完毕");
302 
303         // 将绘制完成后的faceBitmap返回
304         // return srcFace;
305         return null;
306 
307     }
308 
309     public void showProcessBar() {
310         RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.layout_main);
311         progressBar = new ProgressBar(MainActivity.this, null,
312                 android.R.attr.progressBarStyleLargeInverse); // ViewGroup.LayoutParams.WRAP_CONTENT
313         RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
314                 ViewGroup.LayoutParams.WRAP_CONTENT,
315                 ViewGroup.LayoutParams.WRAP_CONTENT);
316         params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
317         params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
318         progressBar.setVisibility(View.VISIBLE);
319         // progressBar.setLayoutParams(params);
320         mainLayout.addView(progressBar, params);
321 
322     }
323 
324 }

分类:

技术点:

相关文章:

  • 2021-11-11
  • 2021-08-18
  • 2021-12-02
  • 2022-12-23
  • 2022-12-23
  • 2022-01-06
  • 2022-12-23
猜你喜欢
  • 2021-12-09
  • 2021-11-27
  • 2021-07-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案