• 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>

     检测多余人脸:

     

  • 相关阅读:
    jq 编写弹窗
    jq 编写选项卡
    event 事件 自定义滚动条 控制文字滚动
    Integer Partition Algorithm
    Implement the integral part logn base 2 with bit manipulations
    **Nim Game hard hard version
    *Check whether a given graph is Bipartite or not
    *Flatten a multilevel linked list
    Priority Queue Implementation
    Find the Minimum length Unsorted Subarray, sorting which makes the complete array sorted
  • 原文地址:https://www.cnblogs.com/haoxr/p/7650642.html
Copyright © 2020-2023  润新知