Android中 Face ServiceFaceDetector簡單一實例,androidFace Service

來源:互聯網
上載者:User

Android中 Face ServiceFaceDetector簡單一實例,androidFace Service

  Android SDK從1.0版本中(API level 1)就已經整合了簡單的Face Service功能,通過調用FaceDetector 我們可以在Android平台上實現Bitmap多Face Service(一張圖中可以有多個人臉)。它尋找人臉的原理是:找眼睛。它返回的人臉資料face,通過調用public float eyesDistance (),public void getMidPoint (PointF point),我們可以得到探測到的兩眼間距,以及兩眼中心點位置(MidPoint)。public float confidence () 可以返回該人臉資料的可信度(0~1),這個值越大,該人臉資料的準確度也就越高。
 

流程
1. 讀取一張圖片至Bitmap (從Resource中,或是從手機相簿中選取)
2. 使用FaceDetector API分析Bitmap,將探測到的人臉資料以FaceDetector.Face儲存在一個Face list中;
3.將人臉框顯示在圖片上。

源碼
activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:padding="10dp" >    <Button        android:id="@+id/btn_select"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="選擇圖片" />    <Button        android:id="@+id/btn_detect"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:text="檢測人臉" />    <ImageView        android:id="@+id/image"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_marginTop="5dp" /></LinearLayout>

MainActivity.java

package com.example.faceandroidtest;import android.app.Activity;import android.app.ProgressDialog;import android.content.Intent;import android.database.Cursor;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.media.FaceDetector.Face;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.provider.MediaStore;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener {    private static final int REQUEST_CODE_SELECT_PIC = 120;    private static final int MAX_FACE_NUM = 10;//最大可以檢測出的人臉數量    private int realFaceNum = 0;//實際檢測出的人臉數量    private Button selectBtn;    private Button detectBtn;    private ImageView image;    private ProgressDialog pd;    private Bitmap bm;//選擇的圖片的Bitmap對象    private Paint paint;//畫人臉地區用到的Paint    private boolean hasDetected = false;//標記是否檢測到人臉    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        paint = new Paint();        paint.setColor(Color.BLUE);        paint.setStrokeWidth(2);        paint.setStyle(Paint.Style.STROKE);//設定話出的是空心方框而不是實心方塊        pd = new ProgressDialog(this);        pd.setTitle("提示");        pd.setMessage("正在檢測,請稍等");    }    /**     * 控制項初始化     */    private void initView(){        selectBtn = (Button) findViewById(R.id.btn_select);        selectBtn.setOnClickListener(this);        detectBtn = (Button) findViewById(R.id.btn_detect);        detectBtn.setOnClickListener(this);        image = (ImageView) findViewById(R.id.image);    }    /**     * 從圖庫選擇圖片     */    private void selectPicture(){        Intent intent = new Intent();        intent.setAction(Intent.ACTION_GET_CONTENT);        intent.setType("image/*");        startActivityForResult(intent, REQUEST_CODE_SELECT_PIC);    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode == REQUEST_CODE_SELECT_PIC && resultCode == Activity.RESULT_OK){            //擷取選擇的圖片            Uri selectedImage = data.getData();            String[] filePathColumn = { MediaStore.Images.Media.DATA };            Cursor cursor = getContentResolver().query(selectedImage,                    filePathColumn, null, null, null);            cursor.moveToFirst();            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);            String selectedImagePath = cursor.getString(columnIndex);            bm = BitmapFactory.decodeFile(selectedImagePath);            //要使用Android內建的Face Service,需要將Bitmap對象轉為RGB_565格式,否則無法識別            bm = bm.copy(Bitmap.Config.RGB_565, true);            cursor.close();            image.setImageBitmap(bm);            hasDetected = false;        }    }//  private void selectPicture(){//      bm = BitmapFactory.decodeResource(getResources(), R.drawable.test1);//      bm = bm.copy(Bitmap.Config.RGB_565, true);//        image.setImageBitmap(bm);//        hasDetected = false;//  }    /**     * 檢測人臉     */    private void detectFace(){        if(bm == null){            Toast.makeText(this, "請先選擇圖片", Toast.LENGTH_SHORT).show();            return ;        }        if(hasDetected){            Toast.makeText(this, "已檢測出人臉", Toast.LENGTH_SHORT).show();        }else{            new FindFaceTask().execute();        }    }    private void drawFacesArea(FaceDetector.Face[] faces){        Toast.makeText(this, "圖片中檢測到" + realFaceNum + "張人臉", Toast.LENGTH_SHORT).show();        float eyesDistance = 0f;//兩眼間距        Canvas canvas = new Canvas(bm);        for(int i = 0; i < faces.length; i++){            FaceDetector.Face face = faces[i];            if(face != null){                PointF pointF = new PointF();                face.getMidPoint(pointF);//擷取人臉中心點                eyesDistance = face.eyesDistance();//擷取人臉兩眼的間距                //畫出人臉的地區                canvas.drawRect(pointF.x - eyesDistance, pointF.y - eyesDistance, pointF.x + eyesDistance, pointF.y + eyesDistance, paint);                hasDetected = true;            }        }        //畫出人臉地區後要重新整理ImageView        image.invalidate();    }    /**     * 檢測映像中的人臉需要一些時間,所以放到AsyncTask中去執行     * @author yubo     *     */    private class FindFaceTask extends AsyncTask<Void, Void, FaceDetector.Face[]>{        @Override        protected void onPreExecute() {            super.onPreExecute();            pd.show();        }        @Override        protected Face[] doInBackground(Void... arg0) {            //最關鍵的就是下面三句代碼            FaceDetector faceDetector = new FaceDetector(bm.getWidth(), bm.getHeight(), MAX_FACE_NUM);            FaceDetector.Face[] faces = new FaceDetector.Face[MAX_FACE_NUM];             realFaceNum = faceDetector.findFaces(bm, faces);            if(realFaceNum > 0){                return faces;            }            return null;        }        @Override        protected void onPostExecute(Face[] result) {            super.onPostExecute(result);            pd.dismiss();            if(result == null){                Toast.makeText(MainActivity.this, "抱歉,圖片中未檢測到人臉", Toast.LENGTH_SHORT).show();            }else{                drawFacesArea(result);            }        }    }    public void onClick(View arg0) {        switch(arg0.getId()){            case R.id.btn_select://選擇圖片                selectPicture();                break;            case R.id.btn_detect://檢測人臉                detectFace();                break;        }    }}

在源碼中先將MAX_FACE_NUM最大可以檢測出的人臉數量設為5。

private static final int MAX_FACE_NUM = 5;//最大可以檢測出的人臉數量

檢測結果

猜測應該是選取人群中識別率最高的5個人頭像,因為最大可以檢測出的人臉數量為5,所以只顯示識別率最高的前5個人頭像。

當將MAX_FACE_NUM最大可以檢測出的人臉數量設為10。

private static final int MAX_FACE_NUM = 10;//最大可以檢測出的人臉數量

同一張圖片檢測結果

參考引用

  • Android API 臉部偵測(Face Detect)
  • 用AndroidSDK中的Face Detector實現Face Service
  • Face++ 官網

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.