新的Camera feature: Face Detection
1. camera app, in packages/apps/Camera/src/com/android/camera/camera.java

startFaceDetection()

stopFaceDetection()

在initializeFirstTime()函数中会调用startFaceDetection() ,以开始做人脸识别的准备动作。

在startFaceDetection中会首先判断getMaxNumDetectedFaces是否大于0,若没有大于0,则表示硬件不支持人脸识别,直接退出函数,否则

mCameraDevice.setFaceDetectionListener(this);
mCameraDevice.startFaceDetection();

设置人脸识别的监听者为this(注意这边的参数,这意味着在mCameraDevice中的mFaceListener其实为这边的package中的camera类),用于回调函数,并调用mCameraDevice的startFaceDetection。

在这文件中还有一个关键函数:

onFaceDetection()

这在mCameraDevice中会调用到,用作最后的显示动作。

这里的mCameraDevice就是framework层的camera类。

这边还有个Faceview类,简单做个介绍,位于
packages/apps/Camera/src/com/android/camera/ui/FaceView.java

public class FaceView extends View implements FocusIndicator{   
....
}

In FaceView:
frameworks/base/media/java/android/media/FaceDetector.java
frameworks/base/graphics/java/android/graphics/Matrix.java
frameworks/base/graphics/java/android/graphics/RectF.java

frameworks/base/graphics/java/android/graphics/drawable/Drawable.java

主要是关于人脸识别后的view的一些操作。

2. 接着上面说mCameraDevice

位于frameworks/base/core/java/android/hardware/Camera.java

相关变量的定义:
    private FaceDetectionListener mFaceListener;
    private boolean mFaceDetectionRunning = false;
    private static final int CAMERA_FACE_DETECTION_HW = 0;
    private static final int CAMERA_FACE_DETECTION_SW = 1;

public interface FaceDetectionListener{
            void onFaceDetection(Face[] faces, Camera camera);//这里调用的就是package中camera类的函数
        }
    public final void setFaceDetectionListener(FaceDetectionListener listener){
            mFaceListener = listener;//设置监听者
    }
    public final void startFaceDetection() {
        if (mFaceDetectionRunning) {
            throw new RuntimeException("Face detection is already running");
        }
        _startFaceDetection(CAMERA_FACE_DETECTION_HW);//真正开始FaceDetection的地方
        mFaceDetectionRunning = true;
    }
    public final void stopFaceDetection() {
        _stopFaceDetection();//停止FaceDetection
        mFaceDetectionRunning = false;

}

private native final void _startFaceDetection(int type);

private native final void _stopFaceDetection();

_startFaceDetection()和_stopFaceDetection()都是jni的方法,即用到本地调用,_startFaceDetection()会调用到android_hardware_Camera_startFaceDetection这个函数:

status_t rc = camera->sendCommand(CAMERA_CMD_START_FACE_DETECTION, type, 0);

这边会调用到Hal层的sendCommand方法,传递CAMERA_CMD_START_FACE_DETECTION消息,在Hal要对这个Message进行处理,以开始处理人脸识别。这边介绍一下ti的做法:

in camera hal:

status_t CameraHal::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
{

……

switch(cmd)
            {
            case CAMERA_CMD_START_SMOOTH_ZOOM:
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_SMOOTH_ZOOM, arg1);
                break;
            case CAMERA_CMD_STOP_SMOOTH_ZOOM:
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);
            case CAMERA_CMD_START_FACE_DETECTION:
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);
                break;
            case CAMERA_CMD_STOP_FACE_DETECTION:
                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
                break;
            default:
                break;
            };

}

遇到CAMERA_CMD_START_FACE_DETECTION这个消息后,会继续调用mCameraAdapter->sendCommand,

之后会继续调用:

case CameraAdapter::CAMERA_START_FD:
             ret = startFaceDetection();
             break;

依然会去调用startFaceDetection这个函数,CameraAdapter中的startFaceDetection并未做什么事情,这里面主要是做一些初始化的设置动作,需要自己实现,我们可以参考OMXFD中的。
hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXFD.cpp  //This file contains functionality for handling face detection.
OMXCameraAdapter::setParametersFD()
OMXCameraAdapter::startFaceDetection()
OMXCameraAdapter::stopFaceDetection()
OMXCameraAdapter::pauseFaceDetection()
OMXCameraAdapter::setFaceDetection()
OMXCameraAdapter::detectFaces()
OMXCameraAdapter::encodeFaceCoordinates()

hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXAlgo.cpp //This file contains functionality for handling algorithm configurations.
OMXCameraAdapter::setAlgoPriority()

hardware/ti/omap4xxx/domx/omx_core/inc/OMX_Core.h    //depend on hardware/ti/omap4xxx/domx modules.
OMX_SetConfig()

hardware/ti/omap4xxx/domx/omx_core/inc/OMX_TI_IVCommon.h

typedef struct OMX_CONFIG_EXTRADATATYPE {
        OMX_U32 nSize;
        OMX_VERSIONTYPE nVersion;
        OMX_U32 nPortIndex;
        OMX_EXT_EXTRADATATYPE eExtraDataType;
        OMX_TI_CAMERAVIEWTYPE eCameraView;
        OMX_BOOL bEnable;
    } OMX_CONFIG_EXTRADATATYPE;

typedef struct OMX_CONFIG_OBJDETECTIONTYPE {
        OMX_U32 nSize;
        OMX_VERSIONTYPE nVersion;
        OMX_U32 nPortIndex;
        OMX_BOOL bEnable;
        OMX_BOOL bFrameLimited;
        OMX_U32 nFrameLimit;
        OMX_U32 nMaxNbrObjects;
        OMX_S32 nLeft;
        OMX_S32 nTop;
        OMX_U32 nWidth;
        OMX_U32 nHeight;
        OMX_OBJDETECTQUALITY eObjDetectQuality;
        OMX_U32 nPriority;
        OMX_U32 nDeviceOrientation;
    } OMX_CONFIG_OBJDETECTIONTYPE;

在notifyEvent中,

case CameraHalEvent::EVENT_FACE:
                    faceEvtData = evt->mEventData->faceEvent;
                    if ( ( NULL != mCameraHal ) &&
                         ( NULL != mNotifyCb) &&
                         ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) ) )
                        {
                        // WA for an issue inside CameraService
                        camera_memory_t *tmpBuffer = mRequestMemory(-1, 1, 1, NULL);
                        mDataCb(CAMERA_MSG_PREVIEW_METADATA,
                                tmpBuffer,
                                0,
                                faceEvtData->getFaceResult(),
                                mCallbackCookie);
                        faceEvtData.clear();
                        if ( NULL != tmpBuffer ) {
                            tmpBuffer->release(tmpBuffer);
                        }
                        }
                    break;

一旦有人脸识别的数据,就回传 faceEvtData->getFaceResult(),给上层的监听者,消息是CAMERA_MSG_PREVIEW_METADATA。

NotificationThread->mAppCallbackNotifier->notificationThread()->

if(mEventQ.hasMsg()) {
        ///Received an event from one of the event providers
        CAMHAL_LOGDA("Notification Thread received an event from event provider (CameraAdapter)");
        notifyEvent();
     }

它实在Callbacknotifier中初始化中另起一个线程用来监听事件,如果有人脸识别的动作的化,则回传相应的结果给上层的监听者以做显示,这跟preview(notifyEvent())是分开,是另外的一份单独的数据。

而在framework层的camera里,会有如下函数进行消息处理:

public void handleMessage(Message msg) {
             switch(msg.what) {
             ......
             case CAMERA_MSG_PREVIEW_METADATA:
                 if (mFaceListener != null) {
                     mFaceListener.onFaceDetection((Face[])msg.obj, mCamera);
                 }
                 return;
    }

这样就可以在预览的界面上看到人脸识别的窗口了。

public static class Face{
        public Face() {
        }
        public Rect rect;
        public int score;
        public int id = -1;
        public Point leftEye = null;
        public Point rightEye = null;
        public Point mouth = null;
    }
    public class Parameters {        //new camera parameters.
        private static final String KEY_MAX_NUM_DETECTED_FACES_HW = "max-num-detected-faces-hw";
        private static final String KEY_MAX_NUM_DETECTED_FACES_SW = "max-num-detected-faces-sw";
    
        public int getMaxNumDetectedFaces() {
            return getInt(KEY_MAX_NUM_DETECTED_FACES_HW, 0);
        }    
    }
}

3.总结

Camera app 和 android api已经准备好,我们的工作主要集中在camera的Hal层。我们需要了解所有的face detection的相关方法以实现它。

Camera Face Detection相关推荐

  1. 行人检测(Pedestrian Detection)资源

    行人检测(Pedestrian Detection)资源 原文链接 http://hi.baidu.com/susongzhi/item/085983081b006311eafe38e7 一.论文 C ...

  2. RPi 2B python opencv camera demo example

    /*************************************************************************************** RPi 2B pyth ...

  3. Pedestrian Detection paper

    一.论文 综述类的文章 [1]P.Dollar, C. Wojek,B. Schiele, et al. Pedestrian detection: an evaluation of the stat ...

  4. 行人检测(Pedestrian Detection)资源与更新

    行人检测相关的网站链接:      [1].Caltech Pedestrian Detection Benchmark: http://www.vision.caltech.edu/Image_Da ...

  5. ### Paper about Event Detection

    Paper about Event Detection. #@author: gr #@date: 2014-03-15 #@email: forgerui@gmail.com 看一些相关的论文. 1 ...

  6. 行人检测资源综述文献

    from: http://blog.csdn.net/GarfieldEr007/article/details/50866089 pedestrian-detection-resource-1-su ...

  7. 电气simulink常用模块_ADAS/AD控制器模块开发:产品构成要素及产品需求

    一.常用缩写: 为了方便描述,以后对下列名称用行业内通用缩写代替: 系统构成要素 - Building Blocks - BB 产品开发文档 - Product Development Documen ...

  8. Pedestrian Identification (2) ——研究现状总结

    最近一直在看行人检测的论文,对目前的行人检测做大概的介绍. 行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域.从2005年以来行人检测进入了一个快速的发展阶段,但是也存 ...

  9. sbc8600_还记得我复制的价值8600万美元的车牌扫描仪吗? 我抓住了它。

    sbc8600 by Tait Brown 泰特·布朗(Tait Brown) 还记得我复制的价值8600万美元的车牌扫描仪吗? 我抓住了它. (Remember the $86 million li ...

最新文章

  1. 【原】开源——基于文件驱动的站点开发
  2. Python之禅--给编程者的掏心窝子的话
  3. POJ1269:Intersecting Lines(判断两条直线的关系)
  4. Java Web系统经常使用的第三方接口
  5. 32行代码AC——L1-027 出租 (20分)(~解题报告~)
  6. echarts --- 多折线图按段显示颜色规则订制
  7. 很认真地聊一聊程序员的自我修养
  8. Jenkins(Pipeline)
  9. CountDownLatch和CyclicBarrier的区别
  10. 【干货】数字化运营:从理论到实践.pdf(附下载链接)
  11. fatal: unable to access ‘https://XXXXX‘: : OpenSSL SSL_read: Connection was reset, errno 10054……
  12. Oracle 有long类型字段的表 使用insert into select 语句 ,出现:ORA-00997 错误
  13. input框,需要隐式显示的时候,不让它自动填充的办法
  14. 玩qq游戏提示计算机内存不足,我有时玩QQ游戏就出现虚拟内存不足.要怎么 – 手机爱问...
  15. Linux日志管理工具 journalctl
  16. 【Vue五分钟】五分钟了解vue的常用实例方法
  17. Android黑科技之微信语音助手-长辈关怀利器
  18. JAVA 使用DateUtils对日期进行格式转换
  19. log(一)——MDC入门
  20. HEU euler path

热门文章

  1. 开源推荐:国内3大主流前端UI表单设计器,千万不要让领导知道
  2. 在Linux(Ubuntu 16.04)下手动下载固定版本或老版本nvidia显卡驱动
  3. 【flask扩展】使用Flask-Mail发送邮件
  4. NewsCenter
  5. 欲戴王冠,必承其重!
  6. 《程序员面试金典(第6版)》面试题 03.06. 动物收容所
  7. phpexcel-常用命令
  8. javascript 中的 innerHTML 是什么意思
  9. 去除Flutter项目dart文件在vscode里出现波浪号
  10. Python-玩转数据-Pandas练习