Camera Face Detection
新的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相关推荐
- 行人检测(Pedestrian Detection)资源
行人检测(Pedestrian Detection)资源 原文链接 http://hi.baidu.com/susongzhi/item/085983081b006311eafe38e7 一.论文 C ...
- RPi 2B python opencv camera demo example
/*************************************************************************************** RPi 2B pyth ...
- Pedestrian Detection paper
一.论文 综述类的文章 [1]P.Dollar, C. Wojek,B. Schiele, et al. Pedestrian detection: an evaluation of the stat ...
- 行人检测(Pedestrian Detection)资源与更新
行人检测相关的网站链接: [1].Caltech Pedestrian Detection Benchmark: http://www.vision.caltech.edu/Image_Da ...
- ### Paper about Event Detection
Paper about Event Detection. #@author: gr #@date: 2014-03-15 #@email: forgerui@gmail.com 看一些相关的论文. 1 ...
- 行人检测资源综述文献
from: http://blog.csdn.net/GarfieldEr007/article/details/50866089 pedestrian-detection-resource-1-su ...
- 电气simulink常用模块_ADAS/AD控制器模块开发:产品构成要素及产品需求
一.常用缩写: 为了方便描述,以后对下列名称用行业内通用缩写代替: 系统构成要素 - Building Blocks - BB 产品开发文档 - Product Development Documen ...
- Pedestrian Identification (2) ——研究现状总结
最近一直在看行人检测的论文,对目前的行人检测做大概的介绍. 行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域.从2005年以来行人检测进入了一个快速的发展阶段,但是也存 ...
- sbc8600_还记得我复制的价值8600万美元的车牌扫描仪吗? 我抓住了它。
sbc8600 by Tait Brown 泰特·布朗(Tait Brown) 还记得我复制的价值8600万美元的车牌扫描仪吗? 我抓住了它. (Remember the $86 million li ...
最新文章
- 【原】开源——基于文件驱动的站点开发
- Python之禅--给编程者的掏心窝子的话
- POJ1269:Intersecting Lines(判断两条直线的关系)
- Java Web系统经常使用的第三方接口
- 32行代码AC——L1-027 出租 (20分)(~解题报告~)
- echarts --- 多折线图按段显示颜色规则订制
- 很认真地聊一聊程序员的自我修养
- Jenkins(Pipeline)
- CountDownLatch和CyclicBarrier的区别
- 【干货】数字化运营:从理论到实践.pdf(附下载链接)
- fatal: unable to access ‘https://XXXXX‘: : OpenSSL SSL_read: Connection was reset, errno 10054……
- Oracle 有long类型字段的表 使用insert into select 语句 ,出现:ORA-00997 错误
- input框,需要隐式显示的时候,不让它自动填充的办法
- 玩qq游戏提示计算机内存不足,我有时玩QQ游戏就出现虚拟内存不足.要怎么 – 手机爱问...
- Linux日志管理工具 journalctl
- 【Vue五分钟】五分钟了解vue的常用实例方法
- Android黑科技之微信语音助手-长辈关怀利器
- JAVA 使用DateUtils对日期进行格式转换
- log(一)——MDC入门
- HEU euler path