FaceDetector(人脸识别)

微软的 how-old.net 把人脸识别技术又大大的火了一把。通过大数据和复杂的算法,能够神奇的预测出照片中人物的性别和年龄。虽然错误率也不低,但是大家都抱着玩一玩乐一乐的心态把照片传上去让机器来鉴定一下自己的颜龄。

Android 早已提供了 FaceDetector 类,今天就来看看如何使用这个类人脸检测吧。

流程:

1.打开文件夹选择照片

2.将照片加载到 bitmap 中并缩放到设置的宽高

3.用 FaceDetector 来检测人脸,得到 Face 类数组(多人脸检测)

4.在照片 bitmap 检测到的人脸上面画上方框和年龄

一、选择照片

将 Intent 设置 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);
            }
        }
    }

最终效果图:

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
抱歉,我是一个语言模型AI,无法编写和运行代码。不过,以下是用insightface实现人脸识别的一般步骤: 1. 安装insightface库 ``` pip install insightface ``` 2. 下载人脸检测模型和人脸识别模型 ``` import os import urllib model_urls = [ 'https://github.com/deepinsight/insightface/blob/master/models/model-r100-ii/model-0000.params?raw=true', 'https://github.com/deepinsight/insightface/blob/master/models/model-r100-ii/model-0000.params?raw=true', 'https://github.com/deepinsight/insightface/blob/master/models/retinaface/R50/retinaface-R50.zip?raw=true' ] model_names = [ 'model-r100-ii/model-0000.params', 'model-r100-ii/model-symbol.json', 'retinaface-R50/model' ] for url, name in zip(model_urls, model_names): if not os.path.exists(name): print('Downloading', name) urllib.request.urlretrieve(url, name) ``` 3. 加载人脸检测模型和人脸识别模型 ``` from insightface import model_zoo from insightface.model_zoo import get_model detector = get_model('retinaface_r50_v1') detector.prepare(ctx_id=-1, nms=0.4) recognition = get_model('arcface_r100_v1') recognition.prepare(ctx_id=-1) ``` 4. 加载人脸库 ``` import cv2 face_db = {} for file in os.listdir('faces'): name = os.path.splitext(file)[0] img = cv2.imread(os.path.join('faces', file)) embedding = recognition.get_embedding(img) face_db[name] = embedding ``` 5. 进行人脸识别 ``` img = cv2.imread('test.jpg') faces = detector.detect(img) for face in faces: embedding = recognition.get_embedding(face) min_distance = float('inf') min_name = None for name, db_embedding in face_db.items(): distance = recognition.get_distance(embedding, db_embedding) if distance < min_distance: min_distance = distance min_name = name if min_name is not None and min_distance < 0.8: cv2.rectangle(img, (face[0], face[1]), (face[2], face[3]), (0, 255, 0), 2) cv2.putText(img, min_name, (face[0], face[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) else: cv2.rectangle(img, (face[0], face[1]), (face[2], face[3]), (0, 0, 255), 2) cv2.putText(img, 'Unknown', (face[0], face[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2) cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上步骤仅供参考,实际使用时需要根据具体情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值