Android人脸检测1(静态图片)

搭建Android人脸识别环境花了很长时间(可以查看之前的文章),解决Android开发中的杂七杂八小问题也耗时不少.

今天记录一下,点击选择照片或者拍照上传照片进行人脸检测的小demo.

(android.media.FaceDetector;方法)

先看效果图:

手机在电脑拍摄的图片:

 

要点说明:

参考:  http://blog.csdn.net/zhandoushi1982/article/details/8613916

 1,  必须要把bitmap转换RGB_565才能检测

bitmap565 = bitmap.copy(Bitmap.Config.RGB_565, true);

2, 给bitmap画框

Canvas canvas = new Canvas(bitmap565);

参考:  https://stackoverflow.com/questions/4918079/android-drawing-a-canvas-to-an-imageview

3, 调用系统相册相机需要配置权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

4, 调用 FaceDetector 感觉很慢,而且会识别多余人脸,最后附图.

5, 后续做动态人脸检测.

 

 

代码:

package com.***.facedetection;


import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.media.FaceDetector;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;

public class MainActivity extends AppCompatActivity {

    private static String CAMERAIMAGENAME = "image.jpg";
    private customImageButton imageButton;
    private TextView textView;
    private Bitmap bitmap;
    private Bitmap resizeBitmap;
    private int numberOfFaceDetected;
    private FaceDetector.Face[] myFace;
    private Bitmap bitmap565;
    private Toast toast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv_face);
        imageButton = (customImageButton) findViewById(R.id.iv_face);
        imageButton.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);

    }


    /**
     * 点击添加照片事件
     *
     * @param v
     */
    public void onClick(View v) {

        int bt_id = v.getId();
        switch (bt_id) {
            case R.id.addPic:
                // 添加照片
                // 打开本地相册
                Intent intent1 = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent1, 101);
                break;

            case R.id.takePhoto:
                // 拍照
                // 打开本地相机
                Intent intent2 = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), CAMERAIMAGENAME));
                intent2.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent2, 102);

                break;

            default:
                break;
        }

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 加判断 不选择照片或者不拍照时不闪退
        //Log.e("data", String.valueOf(data));
        //if (data == null)
            //return;

        bitmap = null;
        switch (requestCode) {
            // 选择图片库的图片
            case 101:
                if (resultCode == RESULT_OK) {
                    try {
                        Uri uri = data.getData();
                        bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;

            // 表示调用本地照相机拍照
            case 102:
                if (resultCode == RESULT_OK) {
                    //Bundle bundle = data.getExtras();
                    //bm = (Bitmap) bundle.get("data");
                    bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/" + CAMERAIMAGENAME);

                }
                break;
            default:
                break;
        }

        Log.e("bitmap", String.valueOf(bitmap));

        if (bitmap == null) {
            toast = Toast.makeText(MainActivity.this, "未选择图像", Toast.LENGTH_SHORT);
            toast.show();
            return;
        }

        // 转换 释放
        bitmap565 = bitmap.copy(Bitmap.Config.RGB_565, true);

        if (!bitmap.isRecycled())
            bitmap.recycle();


        // 识别图片
        detectFace();

        // 画框
        drawFace();


        // 将照片剪裁 bitmap将被释放重新赋值
        int ibWidth = imageButton.getWidth();
        int ibHeight = imageButton.getHeight();
        resizeBitmap = imageButton.cropBitmap(bitmap565, ibWidth, ibHeight);

        imageButton.setBitmap(resizeBitmap);


    }

    private void detectFace() {
        int numberOfFace = 12;
        FaceDetector myFaceDetect;

        int imageWidth = bitmap565.getWidth();
        int imageHeight = bitmap565.getHeight();
        myFace = new FaceDetector.Face[numberOfFace];
        myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);
        numberOfFaceDetected = myFaceDetect.findFaces(bitmap565, myFace);

        textView.setText(String.format("检测到%1$d个人脸", numberOfFaceDetected));

    }

    private void drawFace() {
        Canvas canvas = new Canvas(bitmap565);
        // canvas.drawBitmap(bitmap565, 0, 0, null);
        Paint myPaint = new Paint();
        myPaint.setColor(Color.GREEN);
        myPaint.setStyle(Paint.Style.STROKE);
        myPaint.setStrokeWidth(3);
        for (int i = 0; i < numberOfFaceDetected; i++) {
            FaceDetector.Face face = myFace[i];
            PointF myMidPoint = new PointF();
            face.getMidPoint(myMidPoint);
            float myEyesDistance = face.eyesDistance();
            canvas.drawRect((int) (myMidPoint.x - myEyesDistance * 1.5),
                    (int) (myMidPoint.y - myEyesDistance * 1.5),
                    (int) (myMidPoint.x + myEyesDistance * 1.5),
                    (int) (myMidPoint.y + myEyesDistance * 1.8), myPaint);
        }

    }


}

 

自定义ImageButton类,可以按比例缩放bitmap适应ImageButton居中显示:

package com.***.facedetection;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class customImageButton extends LinearLayout {
    private TextView _textView;
    private ImageView _imageView;

    public customImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        _imageView = new ImageView(context, attrs);
        _imageView.setPadding(2, 2, 2, 2);

        _textView = new TextView(context, attrs);
        _textView.setBackgroundColor(Color.TRANSPARENT);
        _textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
        _textView.setPadding(0, 0, 0, 0);

        setClickable(true);
        setFocusable(true);
        setOrientation(LinearLayout.VERTICAL);
        addView(_textView);
        addView(_imageView);
    }


    public void setText(String text) {
        _textView.setText(text);
    }

    public void setButtonEnable(Boolean bool) {
        _imageView.setEnabled(bool);
    }

    public void clearnImage() {
        _textView.setVisibility(View.VISIBLE);
        _imageView.setImageDrawable(null);
    }

    public void setBitmap(Bitmap bm) {
        _textView.setVisibility(View.GONE);
        _imageView.setImageDrawable(null);
        _imageView.setImageBitmap(bm);

    }


    public Bitmap cropBitmap(Bitmap bm, int ivbWidth, int ivbHeight) {
        Bitmap resizeBmp = null;
        try {

            Matrix matrix = new Matrix();

            float scale;
            if (ivbWidth <= ivbHeight) {
                scale = (float) ivbWidth / bm.getWidth();
                matrix.postScale(scale, scale); //长和宽放大缩小的比例
                resizeBmp = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
            } else {
                scale = (float) ivbHeight / bm.getHeight();
                matrix.postScale(scale, scale);
                resizeBmp = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
            }

            Log.e("scale", scale + "");

            if (!bm.isRecycled())
                bm.recycle();


        } catch (Exception e) {
            e.printStackTrace();

        }
        return resizeBmp;
    }

}

 

布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.***.facedetection.MainActivity">


    <com.***.facedetection.customImageButton
        android:id="@+id/iv_face"
        android:layout_width="match_parent"
        android:layout_height="450dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <TextView
        android:id="@+id/tv_face"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:text="未检测到人脸"
        android:textColor="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/takePhoto"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <Button
        android:id="@+id/takePhoto"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:onClick="onClick"
        android:text="拍照"
        android:textSize="16sp"
        app:layout_constraintBottom_toTopOf="@+id/addPic"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <Button
        android:id="@+id/addPic"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="选择图片"
        android:textSize="16sp"
        android:layout_marginBottom="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


</android.support.constraint.ConstraintLayout>

 

 

 检测多余人脸:

 

 

 

 

 

 

 

posted @ 2017-10-11 15:07  菱花淚硃砂  阅读(1303)  评论(0编辑  收藏  举报