鍍金池/ 教程/ Android/ 人臉檢測-靜態(tài)
多分辨率適配常用目錄
Android 開發(fā)環(huán)境(Eclipse+ADT+Android 5.0)
Android 原型設(shè)計工具探索
Makefile 快速入門
Android Studio的NDK開發(fā)
人臉檢測-靜態(tài)
getprop 與 dumpsys 命令
Maven 編譯開源二維碼掃描項目 zxing
畫布 Canvas
組合控件
Linux 下的模擬器硬件加速
讀取 Excel
android.hardware.camera2 使用指南
橫豎屏切換
Ubuntu 下切換 JDK 版本
拍照和錄像 with Camera
文本與布局
按鈕控制 ViewPager 的左右翻頁
用 TableLayout 偽裝表格顯示數(shù)據(jù)
Preference Activity 使用詳解
模擬器如何重啟?試試 Genymotion!
獲得屏幕物理尺寸、密度及分辨率
語音識別
了解 native activity
Android Studio 導(dǎo)入第三方類庫、jar 包和 so 庫
啟動另一個 App/apk 中的 Activity
APK 簽名
兩個開源的圖表/報表控件
android studio 導(dǎo)出 jar 包(Module)并獲得手機(jī)信息
圖片的 Base64 編解碼
混淆與反編譯
Android Studio 和 Gradle
Android 5.1 SDK 下載與配置
persistableMode 與 Activity 的持久化
adb 取出安裝在手機(jī)中的 apk
Android Studio 中的源代碼管理
Handler 使用中可能引發(fā)的內(nèi)存泄漏

人臉檢測-靜態(tài)

最近微軟的 how-old.net 把人臉識別技術(shù)又大大的火了一把。通過大數(shù)據(jù)和復(fù)雜的算法,能夠神奇的預(yù)測出照片中人物的性別和年齡。雖然錯誤率也不低,但是大家都抱著玩一玩樂一樂的心態(tài)把照片傳上去讓機(jī)器來鑒定一下自己的顏齡。

http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/30-1.png" alt="fig.1" />

人臉識別算法是高深復(fù)雜的,面對著計算機(jī)視覺的種種數(shù)學(xué)公式,我就已經(jīng)投降了。先來簡單的玩玩人臉檢測吧。Android 早已提供了 FaceDetector 類,今天就來看看如何使用這個類人臉檢測吧。

流程:

1.打開文件夾選擇照片

2.將照片加載到 bitmap 中并縮放到設(shè)置的寬高

3.用 FaceDetector 來檢測人臉,得到 Face 類數(shù)組(多人臉檢測)

4.在照片 bitmap 檢測到的人臉上面畫上方框和年齡

一、選擇照片

將 Intent 設(shè)置 Type 和 Action,啟動 activity 選擇照片并得到照片的 uri。

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, OPEN_PHOTO_FOLDER_REQUEST_CODE);

二、加載照片到 bitmap 并縮放

新建一個類 FDView 繼承自 View,就像上一篇文章一樣,對 bitmap 的修改用到了 canvas 的知識。

有兩種辦法將照片加載到 bitmap 中:

1.通過 uri 用 stream 的方式

    public void initBitmap(Uri uri,int width,int height) {
        try {
            ContentResolver resolver = mContext.getContentResolver();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;//need this config
            Bitmap bitmap = BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options);
            mBitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height);//scale the bitmap
            detectFace();
        } catch (Exception ex) {
            Log.e(TAG,"exception: "+ex.getMessage());
        }
    }

2.用照片的真實路徑加載

獲得真實路徑:

        private void initFRViewWithPath(Uri uri) {
            String[] projection =   {MediaStore.Images.Media.DATA};
    //        Cursor cursor = managedQuery(uri, projection, null, null, null);//deprecated
            CursorLoader cursorLoader = new CursorLoader(this,uri,projection,null,null,null);
            Cursor cursor = cursorLoader.loadInBackground();
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();

            String path = cursor.getString(column_index);
            Log.e(TAG,"real path: "+path);
            mFRView.initBitmap(path,mFRView.getWidth (),mFRView.getHeight());
        }

decodeFile:

    public void initBitmap(String path,int width,int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        mBitmap = BitmapFactory.decodeFile(path, options);
        mBitmap = ThumbnailUtils.extractThumbnail(mBitmap,width,height);//scale the bitmap
        detectFace();
    }

三、人臉檢測

    private void detectFace() {
        if(mBitmap != null) {
            mImageWidth = mBitmap.getWidth();
            mImageHeight = mBitmap.getHeight();
            mFaces = new FaceDetector.Face[NUMBER_OF_FACES];
            mFaceDetector = new FaceDetector(mImageWidth, mImageHeight, NUMBER_OF_FACES);
            mNumberOfFaceDetected = mFaceDetector.findFaces(mBitmap, mFaces);
            invalidate();
        }
    }

四、人臉上畫框

在 onDraw 中用 canvas 將檢測到的人臉畫上框并寫上年齡。

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mBitmap != null) {
            canvas.drawBitmap(mBitmap, 0, 0, null);
            Paint paint = new Paint();
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(2);
            paint.setTextSize(50);

            for(int i=0; i < mNumberOfFaceDetected; i++){
                FaceDetector.Face face = mFaces[i];
                PointF pointF = new PointF();
                face.getMidPoint(pointF);
                mEyesDistance = face.eyesDistance();
                canvas.drawRect(
                        (int)(pointF.x - mEyesDistance),
                        (int)(pointF.y - mEyesDistance/2),
                        (int)(pointF.x + mEyesDistance),
                        (int)(pointF.y + mEyesDistance*3/2),
                        paint);
                canvas.drawText("28",pointF.x,pointF.y - mEyesDistance/2-5,paint);
            }
        }
    }

最終效果圖:

http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/30-2.png" alt="fig.2" />

源碼請參考我的開源 demo:[https://code.csdn.net/lincyang/androidwidgetdemo]()