人脸识别

    安卓-广告屏分析工程

    版本日志

    日期 版本 更新说明
    2019.07.24 V1.1 更新底层SDK;
    增加批量鉴权接口;
    开放RGB活体检测接口;开放证件照比对接口
    2019.01.10 V1.0 人脸广告屏分析方案初版

    1. 简介

    您好,欢迎使用百度人脸广告屏解决方案。

    1.1 方案概述

    此方案提供完整的线下广告智能投放、效果监测等一整套解决方案,颠覆传统的粗放投放模式,实现品效合一、数据驱动,赋能广告主科学制定投放决策,助力线下媒体提升点位价值。

    1.2 功能介绍

    1.2.1 受众检测与识别

    离线识别SDK,通过分析线下媒体的摄像头拍摄的视频图像,利用人脸检测、质量检测、人脸识别等功能,为视频中出现的每个受众建立唯一的受众ID。同时,离线识别SDK可以对检测到的每个受众人脸进行抠图,通过与在线API配合,将抠出的人脸图上传云端,建立人脸库,可以实现对受众的管理和运营。

    1.2.2 受众画像分析

    离线识别SDK,通过对线下媒体的摄像头拍摄的视频图像进行处理,实时分析得到视频中出现单个或多个受众的画像。画像内容包括:受众ID、年龄、性别、称谓、表情、眼镜、观看时长、关注度。结合地理位置、时间等信息,建立完备的受众画像,实现线下广告投放精细化和个性化。

    1.2.3 投放效果分析

    离线识别SDK,通过对指定时段内线下媒体的摄像头拍摄的视频图像进行分析,监测该时段内,线下媒体所在区域的人流热度,智能分析受众的动作和行为,并进行语义化解析,形成多维度投放效果报表,帮助广告主改善广告内容,优化投放决策。

    1.3 名词解释

    受众画像中,称谓由年龄和性别的结果而产生,具体产生标准为:

    表1 称谓产生的标准

    • 观看行为:系统检测到人脸后,该人脸头部上下(Pitch)、左右(Yaw)偏转角度在一定范围之内,视为一次观看行为。其中,上下(Pitch)、左右(Yaw)偏转角度的默认范围均为-15°~15°,此范围可根据实际情况进行调整。
    • 观看时长:受众所有观看行为的持续时间,单位为秒。
    • 关注度:观看时长/检测时长*100%
    • 触达人数:从摄像头视频流中检测出的人脸,经过去重后,对应的受众数量。
    • 观看人数:触达人数中有观看行为的受众数量。
    • 检测时长:系统检测到人脸并进行人脸跟踪的全部持续时间,单位为秒。
    • 关注度:观看时长/检测时长*100%
    • 深度观看人数:观看度大于某个值的受众数量,默认值为50%,可根据实际情况进行调整。
    • 点位热度:衡量广告媒体点位的流量热度,其计算公式为:点位热度= 触达人数*0.3 + 观看人数*0.3 + 深度观看人数*0.4​

    1.4 应用场景

    1.4.1 线下媒体广告投放

    无网状态离线运行,精准分析广告触达人数、观看人数、收视率等指标,建立流量漏斗模型,利用数据帮助广告主科学优化投放策略。

    图片

    1.4.2 广告精准营销

    获取线下媒体屏前受众画像,打通线上线下数据,基于画像完成千人千面的广告精准投放。

    1.4.3 有效剔除非真人图片造成的数据影响

    对广告效果进行监播时,利用活体检测能力,剔除掉背景中的人物图片,人物海报等非真人图片造成的影响,使得监播的数据更为真实可靠。

    1.4.4 提升新零售场景业务效率

    零售店、酒店、商场等多种新零售场景,打通广告营销系统与场景业务系统,借助人脸识别完成酒店认证核验、人脸支付等业务,提升新零售场景的业务效率。

    1.5 方案优势

    • 多人脸场景:提供基于多人脸场景的各项人脸检测和识别功能,能够同时支持对4-8人进行处理。
    • 离线/在线通用:能够在离线环境完成各项人脸检测和识别功能,也支持与在线API联动,以建立更大的受众库。
    • 业务功能自定义:可以自定义观看行为等业务功能的标准,极大拓展跨场景的适用性。

    2、集成指南

    2.1 准备工作

    在正式集成前,需要做一些准备工作,完成一些账号、应用及配置,具体如下:

    2.1.1 注册开发者

    • STEP1:点击百度AI开放平台导航右侧的控制台,页面跳转到百度云登录界面,登录完毕后,将会进入到百度云后台,点击「控制台」进入百度云控制台页面;您也可以在官网直接点击免费试用,登录完毕后将自动进入到百度云控制台。
    • STEP2:使用百度账号完成登录,如您还未持有百度账户,可以点击此处注册百度账户。
    • STEP3:进入百度云欢迎页面,填写企业和个人基本信息,注册完毕,至此成为开发者。(如您之前已经是百度云用户或百度开发者中心用户,STEP3 可略过。)
    • STEP4:进入百度云控制台,找到人工智能相关服务面板。
    • STEP5:点击进入「人脸识别」模块。

    2.1.2 获取序列号

    点击“离线识别SDK管理”选项,进入离线SDK管理页面。在此页面,用户将获得五个免费试用的序列号,每个序列号经过激活后,可以在一台设备上使用一个离线SDK。用户可以点击“下载SDK”按钮,下载离线识别SDK。

    完成授权请参考 激活教程

    2.1.3 在线批量鉴权

    采用在线批量鉴权方案,请线下联系百度与您对接的商务接口人

    2.2 集成逻辑

    2.2.1 阈值选择

    1. 观看行为定义
    头部偏转方向 阈值
    上下(Pitch) -15°~15°
    左右(Pitch) -15°~15°
    1. 遮挡检测
    指标 说明 阈值
    left_eye 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    right_eye 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    nose 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    mouth 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    left_cheek 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    right_cheek 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    chin_contour 取值范围[0~1],0为无遮挡,1是完全遮挡 0.6
    1. 质量检测
    指标 说明 阈值
    illumination 取值范围[0~255],脸部光照的灰度值,0表示光照不好。
    以及对应客户端SDK中,YUV的Y分量。
    40
    blurdegree 取值范围[0~1],0是最清晰,1是最模糊。 0.6
    completeness 0或1,0为人脸溢出图像边界,1为人脸都在图像边界内。 0

    2.3 安卓集成说明

    2.3.1 工程配置

    1. 修改包名app->build.gradle->android->defaultConfig -> 您申请license时填的包名
    defaultConfig {
            applicationId ""
            minSdkVersion 15
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
    
            ndk {
                moduleName "facesdk"
                ldLibs "log"
                abiFilters "armeabi-v7a" , "x86", "arm64-v8a" // "armeabi", "x86", "arm64-v8a"
            }
        }
    1. 配置权限
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.GET_TASKS" />

    2.3.2 FaceAuth鉴权接口

    1. 在线鉴权

    备注:鉴权时需手动输入序列号,在有网络的情况下进行鉴权

    /*
     * 初始化鉴权,鉴权方式:通过AIPE 序列码在线激活鉴权
     *  @param context
     * @param licenseKey
     * @param callback
     */
     
    public void initLicenseOnLine(final Context context, final String licenseKey, final AuthCallback callback)
    • 方法功能:初始化鉴权,进行远程网络鉴权
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    context 当前上下文 context 上下文,传当前的 application 即可 Context Y
    licenseKey 申请的鉴权码 申请的序列码 String Y
    callback 鉴权结果 void Response(int code, String response) code:0:成功;1:加载失败; response : 结果信息 AuthCallback Y
    • 接口调用:
     faceAuth = new FaceAuth();
     faceAuth.initLicenseOnLine(this, key, new Callback() {
         @Override
         public void onResponse(final int code, final String response) {
         
         }
     });
    1. 离线鉴权
    /**
     * 初始化鉴权,鉴权方式:离线激活(通过license.zip 文件进行鉴权)
     * @param context
     * @param callback
     */
     public void initLicenseOffLine(final Context context, final Callback callback) 
    • 方法功能:进行离线鉴权
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    context 当前上下文 context上下文,传当前的 application 即可 Context Y
    callback 鉴权结果 void Response(int code, String response) code:0:成功;1:加载失败; response : 结果信息 AuthCallback Y
    • 接口调用:
    faceAuth = new FaceAuth();
     faceAuth.initLicenseOffLine(this, new Callback() {
         @Override
         public void onResponse(final int code, final String response) {
         
         }
     });
    1. 在线批量鉴权
    /**
     * 初始化鉴权,鉴权方式:在线批量授权
     * @param context
     * @param callback
     */
    void initLicenseBatchLine(final Context context, final String licenseID, final Callback callback)
    • 方法功能:在线批量鉴权
    • 方法参数:
    参数名 含义
    context 当前上下文
    licenseID 鉴权码 (sk)
    callback 鉴权结果 void onResponse(int code, String response)
    code 0 : 成功;code 1 加载失败
    response 结果信息
    • 接口调用:
    faceAuth = new FaceAuth();
    faceAuth.initLicenseBatchLine(this, "", new Callback() {
           @Override
           public void onResponse(final int code, final String response) {
                           
           }
     });

    2.3.3 初始化SDK

    // 初始化SDK
     public static BDFaceSDKManager mFaceSDKManager = BDFaceSDKManager.getInstance();
    • 加载模型

    注: 共包括 检测模型、质量检测模型、表情情绪模型、 特征提取模型、活体模型; 2.进行特征比对时必须加载 检测模型、质量检测模型、表情情绪模型、特征提取模型 3.进行活体检测时必须加载 检测模型、质量检测模型、表情情绪模型、活体检测模型

     // 特征提取模型, true 为加载该模型,false为不加载该模型, 默认为true
     public boolean isFeatureStatus = true;
     // 活体检测模型, true 为加载模型, false 为加载该模型
     public boolean isLiveStatus = true;
    • 接口调用:

    人脸分析、特征提取模型加载:

    BDFaceSDKManager.getInstance().isLiveStatus = false;
    BDFaceSDKManager.getInstance().initSDK(this);
    • 活体检测模型加载:
    BDFaceSDKManager.getInstance().isFeatureStatus = false;
    BDFaceSDKManager.getInstance().initSDK(this);

    2.3.4 人脸分析

    // 人脸分析
    public void faceTrack(final Handler handler, BDFaceImageInstance imageInstance)
    • 方法功能:实现人脸检测,获取活体分值及人脸属性
    • 方法参数:
    字段名称 含义 类型 必传
    handler 利用消息机制进行人脸框的绘制 Handler Y
    imageInstance 将获取到的帧图片送检 BDFaceImageInstance Y
    • 接口调用:
        //实现人脸检测,获取活体分数及人脸属性
        
        BDFaceSDKManager mFaceSDKManager = BDFaceSDKManager.getInstance();
        
        private void decodeRun(final byte[] data) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    bdFaceImageInstance = new BDFaceImageInstance(data, CameraUtils.DEFAULT_HEIGHT,
                            CameraUtils.DEFAULT_WIDTH, BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_YUV_420,
                            0, 0);
                    mFaceSDKManager.faceTrack(handler, bdFaceImageInstance);
                    frame_stack_counter--;
                    if (bdFaceImageInstance != null){
                        bdFaceImageInstance.destory();
                    }
                }
            };
            handler.post(runnable);
           
        }

    2.3.5 证件照比对

    特征值获取

     // 特征提取
     public byte[] extractFeature(Context context, String imgPath)
    • 方法功能:获取图像的特征数据
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    context 当前上下文 context 上下文,传当
    前的application即可
    Context Y
    imgPath 图像数据 图片地址 String Y
    • 接口调用:
    BDFaceSDKManager bdFaceSDKManager = BDFaceSDKManager.getInstance();
    first = bdFaceSDKManager.extractFeature(FaceFeatureActivity.this, "pic/camera1.jpg");

    获取提征值的返回值

    public FaceInfo[] getFaceInfos() 
    	{
            return faceInfos;
        }
    • 接口调用:
    BDFaceSDKManager bdFaceSDKManager = BDFaceSDKManager.getInstance();
    FaceInfo firstFaceInfo = bdFaceSDKManager.getFaceInfos()[0];

    特征比对

    // 特征比对
    public float featureCompare(byte[] first, byte[] second)
    • 方法功能:将获取到的获取到的图像进行比对;
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    first 生活照图片 特征分值 byte[] Y
    second 证件照图片 特征分值 byte[] Y
    • 接口调用:
    BDFaceSDKManager bdFaceSDKManager = BDFaceSDKManager.getInstance();
    bdFaceSDKManager.featureCompare(first, second)

    2.3.6 活体检测

    // 活体检测
    public void getFaceLive(Context context, String imagePath)
    • 方法功能:通过此方法检测静默活体的分值
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    context 当前上下文 context 上下文,传当
    前的application即可
    Context Y
    imgPath 图像数据 图片地址 String Y
    • 接口调用:
     bdFaceSDKManager.getFaceLive(mContext, "pic/camera1.jpg");

    2.3.7 Face Info(检测获取到的数据)

    检测到的总人数、观看广告的总人数、 所有观看的总时长

      private int totalPeople;  // 触达人数
      private int viewPeople;   // 观看人数
      private long totalViewTime;  // 所有人观看的总时长(ms)
    • 接口调用:
      // 检测后的数据
    
      FaceInfo faceInfo = new FaceInfo();
      // 触达人数
      int totalPeople = faceinfo.getTotalPeople();
      // 观看人数
      int viewPeople = faceInfo.getViewPeople();
      // 观看时长
      long totalViewTime = faceInfo.getTotalViewTime(); 

    2.3.8 BDFaceInfoManager

    获取深度观看人数

    /**
     * 获取深度观看人数
     */
     public int getDepPerson()
    • 接口调用:
    BDFaceInfoManager.getInstance().getDepPerson()

    获取点位热度

     /**
      * 点位热度
      */
      public double getPointHeatdegree(FaceInfo faceInfo) 
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    faceInfo 得到观看人数 人脸检测得到的数据 FaceInfo Y
    • 接口调用:
    BDFaceInfoManager.getInstance().getPointHeatdegree(faceinfo);

    获取男性人数

    /**
      * 男性人数
      */
     public int getMaleCount()
    • 接口调用:
    BDFaceInfoManager.getInstance().getMaleCount();

    获取女性人数

    /**
      * 女性人数
      */
     public int getFemaleCount()
    • 接口调用:
    BDFaceInfoManager.getInstance().getFemaleCount();

    姿态角过滤

    /**
         * 抬头值为负值 默认为-15
         * 低头值为正值 默认为15
         * 左偏值为负值 默认为-15
         * 右偏值为正值 默认为15
         */
        public void setAttitudeAngle(int lookUp, int lowHead, int leftDeviation, int rightDeviation)
    • 方法参数:
    字段名称 含义 参考值 类型 必传
    LookUp 抬头值 负值 默认为 -15 int Y
    lowHead 低头值 正值 默认为 15 int Y
    leftDeviation 左偏值 负值 默认为 -15 int Y
    rightDeviation 右偏值 正值 默认为 15 int Y
    • 接口调用:
    BDFaceInfoManager.getInstance().setAttitudeAngle(-15,15,-15,15);

    清空历史数据

    /**
     * 清空历史记录
     */
     public void clearRecord()
    • 接口调用:
     BDFaceInfoManager.getInstance().clearRecord();

    2.3.9 BDFacePerson(人脸基本信息)

    faceID

    /**
    * 人脸ID  
    */
    public  int getFaceID(){
    	return faceID;
    }
    • 接口调用:
    for (BDFacePerson person : bdFacePersonList){
    	person.getFaceID();
    }

    年龄

    /**
    * 获取年龄  
    */
    public float getAge(){
    	return age;
    }
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	person.getAge();
    }

    性别

    /**
    * 获取性别
    */
     public int getGender() {
            return gender;
        }
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	/**
    	* 返回值为0 男性
    	* 返回值为 1 为女性  
    	*/
    	person.getGender();
    }

    是否戴眼镜

    /**
    * 是否带眼睛
    */
     public int getGlasses() {
            return glasses;
        }
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	/**
    	* 返回值为0 不戴眼睛, 否则为戴眼睛 
    	*/
    	person.getGlasses();
    }

    情绪

    /**
    * 情绪
    */
    public int getEmotion() {
            return emotion;
        }
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	/**
    	* 返回值为0 生气
    	* 返回值为1 恶心
    	* 返回值为2 恐惧
    	* 返回值为3 开心
    	* 返回值为4 伤心
    	* 返回值为5 惊讶 
    	* 返回值为6 中性  
    	*/
    	person.getEmotion();
    }

    关注度

     /**
      * 关注度
      */
        public int getGazePrecent()
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	person.getGazePrecent();
    }

    观看时长

     /**
      * 返回个人观看时间
      */
      public long getViewTime() 
    • 接口调用:
    for (BDFacePerson person :bdFacePersonList){
    	person.getViewTime();
    }

    2.3.10 FaceManager

    获取指定时间段内的监播数据

     /**
         * 获取指定时间段内的监播数据 * @param start 开始时间(ms) * @param end 结束时间(ms)
         *
         * @return
         */
        public FaceInfo getRange(long start, long end) {
    • 方法参数:
    字段名称 含义 类型 必传
    start 指定时间的开始时间 long Y
    end 指定时间的结束时间 long Y
    • 接口调用:
     bdFaceManager = FaceManager.getInstance();
     FaceInfo faceInfoI = bdFaceManager.getRange(mFirstTime, System.currentTimeMillis());

    获取当前时间往前推 playTime 内的监播信息

    /**
         * 获取当时时间往前推 playTime 内的监播信息 * @param playTime
         *
         * @return
         */
        public FaceInfo getRange(long playTime)
    • 方法参数:
    字段名称 含义 类型 必传
    playTime 往前的推的时间 long Y
    • 接口调用:
    // 向前推3秒内的监播信息
     bdFaceManager = FaceManager.getInstance();
     FaceInfo faceInfo = bdFaceManager.getRange(3000);
    一篇
    安卓-人证核验工程
    一篇
    人脸注册工具平台