• 现在关于人脸识别的SDK其实有很多,诸如face++、百度大脑之类的,他们都为开发者免费提供人脸识别的接口。阿里也和face++合作,实现了支付宝的刷脸支付。但是很遗憾,网上关于识别一段视频中的用户行为(诸如摇...

    现在关于人脸识别的SDK其实有很多,诸如face++、百度大脑之类的,他们都能为开发者免费提供人脸识别的接口。阿里也和face++合作,实现了支付宝的刷脸支付。

    但是很遗憾,网上关于识别一段视频中的用户行为(诸如摇摇头,眨眨眼,微笑)的资料很少,可能是技术没有公开,所以只能自己去想解决方法了。本人最近在做一个关于微信小程序的毕业设计,所以想到了把这两个技术结合下,这里写篇博客,为大家解解惑吧,纯是自己的一些想法,如果大家有疑惑或者更好的建议,可以发邮件联系我(andyliwr@outlook.com)。


    大致的解决方案如下
    这里写图片描述

    图可能不是很清晰,请看这里

    1. 用户在微信小程序中拍摄一段视频
    2. 将用户拍摄的视频传到七牛云服务器
    3. 借助七牛云服务器的媒体处理api对视频每隔一定时间截图,形成一张张视频切图
    4. 使用百度大脑的人脸识别api分析每张图中用户的行为,最后得出结论

    现在开始coding:

    A. 先初始化一个微信小程序的项目,然后新建一个video页面,这个页面的js中需要首先引入七牛云上传文件的js—qiniuUpload.js,然后绑定拍摄视频的按钮的事件—chooseVideo,代码大致如下:

    chooseVideo: function () {
        initQiniu();
        var that = this;
        wx.chooseVideo({
          sourceType: ['camera', 'album'],
          camera: 'front',
          maxDuration: 40,
          success: function (res) {
            console.log('拍照之后:');
            console.log(res);
            that.setData({
              src: res.tempFilePath
            });
            //七牛上传文件
            var vedioObject = res;
            var filePath = res.tempFilePath;
         },error: function(err){
           console.log(err)
         }
       }  

    这样就把用户在拍摄之后的视频信息(时长,高度,宽度,临时存储地址拿到了),接下来就是上传到七牛云服务器了。

    B. 将视频上传到七牛云服务器
    上传文件到七牛过程呢,有一点小复杂,建议大家先去看下七牛的官方技术文档,这里后台我是用的是php,但是实际上七牛的SDK几乎支持所有的主流语言,所以对php不熟悉的同学也不用太担心。
    大致的流程就是先搭建一个获取上传token的接口,在上传文件的时候你需要首先请求这个接口,获得的token是作为上传函数的必要参数,这是使用七牛PHP SDK的代码:

    <?php
      require '../qiniu-sdk/autoload.php';
      use Qiniu\Auth;
      // 用于签名的公钥和私钥
      $accessKey = 't5tBss9FrousfymdmFw4ki2fscwZ8qGaIw8SZmX8';
      $secretKey = 'uASYB6XxzJy9tLWeGsLaNaQyX4bVafIVh6Dpgvxo';
      // 初始化签权对象
      $auth = new Auth($accessKey, $secretKey);
    
      // 空间名  https://developer.qiniu.io/kodo/manual/concepts
      $bucket = 'andyliwr-server';
      // 生成上传Token
      $upToken = $auth->uploadToken($bucket);
      $returnData = array('uptoken'=>$upToken);
      echo json_encode($returnData);

    然后就是在微信小程序中调用七牛的上传api,这里感谢未知名大神的源码贡献,建议好好看看README,里面的qiniuUpload.js已经帮我们封装好了,直接设置定义参数,然后调用initQiniu(),就可以使用qiniuUploader.upload的上传函数,需要设定的参数如下:

    var options = {
        region: 'SCN', // 华东区,生产环境应换成自己七牛帐户bucket的区域
        uptokenURL: 'https://xxxxx/uploadImg.php', // 生产环境该地址应换成自己七牛帐户的token地址,具体配置请见server端
        domain: 'https://xxxxx/' // 生产环境该地址应换成自己七牛帐户对象存储的域名
      };

    大致过程如下
    - 从 github 上下载qiniuUploader.js,导入小程序工程。

    • 在使用 SDK 之前,您必须先注册一个七牛云帐号,并登录控制台获取一对有效的 AccessKey 和 SecretKey,您可以阅读 如何接入七牛 安全机制 以进一步了解如何正确使用和管理密钥 。

    • SDK 依赖服务端颁发 uptoken,可以通过以下二种方式实现:

    • 您需要了解您的七牛存储空间设置在那个区域,比如华东,华南等,参见区域设置

    后端服务应提供一个 URL 地址,供小程序请求该地址后获得 uptoken。请求成功后,服务端应返回如下格式的 json(至少包含 uptoken 字段):

    {
        "uptoken": "0MLvWPnyya1WtPnXFy9KLyGHyFPNdZceomL..."
    }

    根据你创建的七牛存储空间,把对应的 https 上传地址添加到小程序的访问白名单中,方法如下:

    1. 登录 微信公众平台,前往 设置 - 开发设置,点击 服务器配置 下的「修改」链接。
    2. 修改 uploadFile 域名(比如华北 https 上传地址为:https://up-z1.qbox.me,地址不清楚请参见https地址附录)
    3. 如果需要下载文件,则还需要一同设置 downloadFile 域名,为你的 bucket 下载地址
    4. 保存即可
    字段名 内容
    request 域名 https://yourServce.com
    uploadFile 域名 https://up.qbox.me (根据存储区域填写)
    downloadFile 域名 https://baldkf.bkt.clouddn.com

    存储区域对应 HTTPS 地址,参考官方文档

    存储区域 区域代码 HTTPS 地址
    华东 ECN https://up.qbox.me
    华北 NCN https://up-z1.qbox.me
    华南 SCN https://up-z2.qbox.me
    北美 NA https://up-na0.qbox.me

    配置好参数之后,你就应该可以体验下看看能否成功上传视频了了,ps:我这里讲得比价笼统,不会的直接下再小程序的源码,开始整。

    C. 视频上传成功之后,接下就是分解视频了,这里有必要说下七牛云的媒体处理api,就那存在我空间里的一段视频来说,我想拿到它在第一秒时的切图,只需要在视频地址后面带上参数?vframe/jpg/offset/1,比如上述视频的第一秒切图就是https://olpkwt43d.qnssl.com/girl.mp4?vframe/jpg/offset/1,第二秒就是https://olpkwt43d.qnssl.com/girl.mp4?vframe/jpg/offset/2

    所以想要获取到所有切图只需要结合视频时长写一个循环就好了,另外两个参数w是视频的宽度,h是视频的高度,这些需要微信小程序发送给后台:

    var allPicture = [];
    for(var i=0; i<vedioObject.duration; i++){
      allPicture.push(res.imageURL+'?vframe/jpg/offset/'+i+'/w/'+vedioObject.width+'/h/'+vedioObject.height+'/rotate/0');
    }
     wx.request({
       url: https://xxxxx/analysis/request/AipFace.php + '?video_url=' + res.imageURL + '&duration=' + vedioObject.duration + '&width=' + vedioObject.width + '&height=' +vedioObject.height, //仅为示例,并非真实的接口地址
       header: { 'content-type': 'application/json' },
       success: function (res) { ..........

    D: 使用百度API做人脸分析
    同样的百度API虽然对个人用户免费但是需要注册一个appid,这里建议去看下百度的文档,我这里就不多说了,不会的直接下载代码

    最后对接后返回的结果做个检测,isSimle为true则表示用户微笑了:

    var isSimle = res.data.result.some(function(item){
     if(item.result instanceof Array){
       return item.result.some(function(item2){
         return item2.expression == '1';
       })
     }else{
       return item.result.expression == '1';
     }
    });

    最后,觉得有啥不懂的,你可以联系我,踩坑是肯定的,做程序员咱们就得有这觉悟,不懂的你可以联系我(andyliwr@outlook.com),也可以关注我的github(https://github.com/Andyliwr).

    展开全文
  • 实人认证:是指依托活体检测、人脸比对等生物识别技术、证件OCR识别技术等进行的自然人真实身份的校验服务。...我们知道,微信公众号开发中,jssdk中只有图片相关的接口方案,并没有捕获人脸相关的接口服务,...

    实人认证:是指依托活体检测、人脸比对等生物识别技术、证件OCR识别技术等进行的自然人真实身份的校验服务。
    有些业务需求中,我们想要更安全准确的获取用户的真实身份,避免虚假信息的产生,就会要求用户进行实人认证,说的简单点,就是让用户拿着手机对着屏幕摇摇头,张张嘴,眨眨眼之类的,检测人脸动作后,校验真实性。
    我们知道,微信公众号开发中,jssdk中只有图片相关的接口方案,并没有捕获人脸相关的接口服务,所以,我们想要实现这一需求,就要使用一些云服务提供的服务方案,这里笔者采用了阿里云的实人认证服务

    首先,开发者可以阅读快读入门,了解实人认证的基本流程,以及前期准备,开发者需要使用阿里云账号登录实人认证产品详情页,开通这一业务。

    其次,开发者可以直接阅读认证方案,查看H5+服务端接入这一认证方案,App应用可以直接无线SDK+服务端接入这一项。

    接口操作流流程如下:
    微信端用户调接口向服务器发起认证请求,请求参数中应该带上用户真实姓名,身份证号,身份证正反面图片地址(可不传),这时,服务器向阿里云服务器请求认证,获取认证带有token的URL,并将这一url返回给微信端。
    此时,微信端拿到了实人认证的URL路径,直接访问就可以跳转到阿里云的实人认证服务,用户需要做一些摇摇头,眨眨眼,张张嘴之类的动作,就可以完成认证。
    一般在认证完成后,我们希望跳转到我们指定的成功或者失败页面,所以,我们可以在跳转这个认证流程页面入口URL之前,添加上两个参数:
    1.认证通过跳转URL:{认证流程页面入口URL}&successRedirect={认证通过时重定向URL}
    2.认证失败跳转URL:{认证流程页面入口URL}&failRedirect={认证不通过时重定向URL}

    重定向URL就是我们前端的页面。
    注意:重定向 URL 需要加上协议头,并先使用 encodeURIComponent 编码后再拼接。

    时序图如下:
    在这里插入图片描述
    到这里,实人认证的业务流程基本完毕,主要工作都是由后端开发人员来完成,前段人员只需要通过后台提供的接口获取url即可。


    欢迎关注博主:小圣贤君,有问题可以留言哦~

    展开全文
  • 这里就在微信小游戏中尝试一下。 语音交互自然需要一个对象,像我这种手残人士最适合的设计当然就是卡通的小动物了。经过多次修改,在iPad上完成了形象设计(有点丑,有点歪,大家不要见怪): 设计好形象之后就...

    之前在unity里尝试用过语音控制,当时的想法是实时控制游戏角色的移动与攻击,这在通过在线api解析语义的方式下体验一般,不过也想到在实时性要求不那么高的互动场景应该可以用起来。这里就在微信小游戏中尝试一下。

    语音交互自然需要一个对象,像我这种手残人士最适合的设计当然就是卡通的小动物了。经过多次修改,在iPad上完成了形象设计(有点丑,有点歪,大家不要见怪):

    形象

    设计好形象之后就可以设计动画了。一帧一帧的画出连贯的动作。因为偷懒,所以一个动画也就几帧,准备了下面几个动画:

    1. 眨眼。1帧,空闲状态的时候播放,避免什么都不做的时候画面看起来太死板。
    2. 挠头。2帧,录音结束发给服务器等待服务器结果的时候播放,使得能在话音刚落时就给出反应。
    3. 微笑。1帧,对它说“笑一个”的时候播放。
    4. 举牌子。3帧,狗狗不会说话,要通过写字的方式和玩家交流。

    接下来就可以参考飞机示例,完成游戏的代码部分。

    首先新建一个class InterAction,在constructor中进行各种初始化,主要是加载一些图片资源,注册事件等:

    constructor(c, returnTitle) {
        ctx = c
        this.returnTitle = returnTitle
    
        this.bg = wx.createImage()
        this.bg.src = 'images/bg2.png'
    
        this.recordBtn = wx.createImage()
        this.recordBtn.src = 'images/record.png'
        this.recordBtnDown = wx.createImage()
        this.recordBtnDown.src = 'images/recorddown.png'
        this.btn = this.recordBtn
    
        this.dog = new Dog()
    
        this.idleFrameCount = 0
    
        this.result = ''
    
        this.recorderManager = wx.getRecorderManager()
    
        this.recorderManager.onStop(this.onRecordEnd.bind(this))
    
        this.restart()
      }
    
      restart() {
        this._touchStartHandler = this.touchStartHandler.bind(this)
        wx.onTouchStart(this._touchStartHandler)
    
        this._touchEndHandler = this.touchEndHandler.bind(this)
        wx.onTouchEnd(this._touchEndHandler)
    
        requestAnimationFrame(this.loop.bind(this))
      }

    之后,可以看到主线程结构和飞机的基本一样:

    loop() {
        this.update()
    
        this.render()
    
        requestAnimationFrame(this.loop.bind(this))
      }

    在update和按钮、录音的回调函数中更新状态,在render中显示当前帧的内容。

    录音结束后,调用happycxz提供的接口进行语音解析:

    onRecordEnd(res) {
       // 向服务器发送录音文件
       let url = 'https://api.happycxz.com/wxapp/mp32asr'
       this.dog.playAnimation('thinking', 0, true)
       this.idleFrameCount = 0
       this.processFileUploadForAsr(url, res.tempFilePath)
     }
    
     processFileUploadForAsr(url, filePath) {
        wx.uploadFile({
          url: url,
          filePath: filePath,
          name: 'file',
          formData: { 'appKey': appkey, 'appSecret': appsecret, 'userId': UTIL.getUserUnique()},
          header: {'content-type': 'multipart/form-data'},
          success: function(res) {
            let nliResult = this.getNliFromResult(res.data)
            let stt = this.getSttFromResult(res.data)
    
            let result = ''
            if (nliResult != undefined && nliResult.length != 0) {
              result = nliResult[0].desc_obj.result
            } else {
              result = '出了点问题'
            }
            this.handleResult(result)
          }.bind(this),
          fail: function (res) {
            wx.showModal({
              title: '提示',
              content: "网络请求失败,请确保网络是否正常",
              showCancel: false,
              success: function (res) {
              }
            })
          }.bind(this)
        })
      }

    处理返回结果:

    handleResult(res) {
        if (res.length > 6) {
          res = res.substr(0, 6)
        }
        this.result = res
        if (this.result == '微笑') {
          this.dog.playAnimation('smile', 0, true, 60)
          this.idleFrameCount = 0
        } else if (this.result == 'exit') {
          wx.offTouchStart(this._touchStartHandler)
          wx.offTouchEnd(this._touchEndHandler)
          this.returnTitle()
        } else {
          this.dog.playAnimation('answer', 
                                  0, 
                                  false, 
                                  240, 
                                  function () {
                                    ctx.fillStyle = "#ffffff"
                                    ctx.font = "15px Arial"
    
                                    ctx.fillText(
                                      this.result,
                                      constants.screenWidth * 17 / 32,
                                      constants.screenHeight * 15 / 32
                                    )}.bind(this), 
                                  2)
          this.idleFrameCount = 0
        }
      }

    Dog是继承自我扩展之后的Animation类,主要的改动有两个,一个是支持多个动画,另一个是在playAnimation时增加了多个参数,可以控制动画循环的方式,并可以指定在特定的帧显示时调用的回调函数。具体的代码可以看文末的代码包,这里就不多说了。

    最后来看看测试效果。

    待机状态

    按下录音键,说话,松开后会做挠头动作(有点难看),等待一段时间会举起牌子显示结果。目前只在olami平台配置了闲聊、24点和算术功能。为了适应牌子大小,结果做了截断处理。下面是几个测试例子:

    笑一个/笑一笑:会做出笑脸
    再见/拜拜:会返回标题界面
    其他:会通过牌子上显示文字信息

    另外,代码中还包含了一个跳跃的小游戏,通过在主界面点击开始可以进入。如果进一步开发,可以把小游戏的分数做为奖励,在互动界面购置一些装饰品之类的,应该会增加不少游戏的趣味性。

    附:

    此项目源码地址:https://gitee.com/stdioh_cn/jumpingdog

    展开全文
  • 当前产品设计和开发的一个主要技术趋势除了响应式外,还有尽量使用CSS/HTML5技术替代图片,这样可以获得很好的设计扩展性和页面访问性能。本文是对一个使用纯CSS构建卡通人物肖像技术的介绍,非常酷的设计和效果。

    产品设计技术趋势

    当前产品设计和开发的一个主要技术趋势除了响应式外,

    还有尽量使用CSS/HTML5技术替代图片,这样可以获得很好的设计扩展性和页面访问性能。

    CSS卡通实例

    下面就是一个英国WEB工程师设计开发的一个非常酷的卡通头像,使用纯CSS实现,还可以简单的切换肤色:)

    辛普森家族卡通头像

    示范页面访问链接,辛普森家族头像

    注:辛普森家族(Simpson family)是美国动画情景喜剧《辛普森一家》中的一支虚构家族。

    使用的技术

    和艺术家素描使用的技术有异曲同工之处,首先把每个人物的脸拆解为不同的形状,然后逐步拼凑成肖像。下面就是拆解后的辛普森人物模型:


    按照上述模型,依次构造出头发、头部、眼睛、鼻子、耳朵、嘴巴、下巴、脖子的CSS DIV块,然后使用绝对位置拼在一起,

    Bart的“头部”示范CSS代码如下:

    position: absolute;
    top: 20px;
    left: 33px;
    width: 9px;
    height: 7px;
    background: #fbd800;
    border-top: 1px solid #110b00;
    border-left: 1px solid #110b00;
    -webkit-transform: rotate(25deg) skew(23deg, 16deg);
    -ms-transform: rotate(25deg) skew(23deg, 16deg);
    transform: rotate(25deg) skew(23deg, 16deg);
    -webkit-border-radius: 2px 0 0 0;
    -moz-border-radius: 2px 0 0 0;
    border-radius: 2px 0 0 0;

    更多CSS代码请访问示范代码页面


    by iefreer

    展开全文
  • 之前已经写好了人脸图片入百度云人脸库,接下来是要将即时拍照的人脸与人脸库的人脸进行对比,比对两张图片中人脸的相似度,返回相似度的值。 获取某个学生的信息// 获取某个学生的信息 public function select($...
         之前已经写好了人脸图片入百度云人脸库,接下来是要将即时拍照的人脸与人脸库的人脸进行对比,比对两张图片中人脸的相似度,返回相似度的值。

     获取某个学生的信息
    // 获取某个学生的信息
        public function select($id=''){
          $where['id'] = $id;
          $ret = M('student')->where($where)->find();
          return $this->ajaxReturn(array('msg'=>$ret));
        }

    获取全部学生的信息

     // 获取全部学生信息
        public function select_index(){
          $pagesize=10;
          $condition = $_GET['condition'];
          $where=array();
          if(!empty($condition)){
            $where['a.no|a.name']=$condition;
          }
          $data = M('student')->
                  alias('a')->
                  where($where)->
                  // join('__IMAGE__ b ON b.no=a.no')->
                  page($_GET['page'],$pagesize)->
                  select();
          foreach ($data as &$row) {
            $path = $row['path'];
            if(!empty($path)){
              if(!file_exists($path)){
                $dir = dirname($path);
                mkdir($dir,0777,true);
                file_put_contents($path, base64_decode($row['base64']));
              }
              $row['path'] = self::HOST . ltrim($path,'.');
            }
            unset($row['base64']);
          }
          $this->ajaxReturn(array('data'=>$data));
        }
    刷脸登录
    // 刷脸登录
        public function login(){
          // 上传文件路径
          $dir = "./Uploads/temp/";
          if(!file_exists($dir)){
            mkdir($dir,0777,true);
          }
          $upload = new \Think\Upload();
          $upload->maxSize = 2048000 ;// 设置附件上传大小
          $upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
          $upload->savepath = '';
          $upload->autoSub = false;
          $upload->rootPath = $dir; // 设置附件上传根目录
          // 上传单个文件
          $info = $upload->uploadOne($_FILES['file']);
          if(!$info) {// 上传错误提示错误信息
              echo json_encode(array('error'=>true,'msg'=>$upload->getError()),JSON_UNESCAPED_UNICODE);
          }else{// 上传成功 获取上传文件信息
            $file = $dir . $info['savepath'].$info['savename'];
            $image = base64_encode(file_get_contents($file));
            $client = $this->init_face();
            $options['liveness_control'] = 'NORMAL';
            $options['max_user_num']  = '1';
            $ret = $client->search($image,'BASE64','1001',$options);
            // echo json_encode($ret,JSON_UNESCAPED_UNICODE);
            // exit;
            if($ret['error_code']==0){
              $user = $ret['result']['user_list'][0];
              $no = $user['user_id'];
              $score = $user['score'];
              if($score>=95){
                $data = M('student')->where("no = '{$no}'")->find();
                $data['score'] = $score;
                // $data['name'] = json_decode($data['name'],true);
                // $data['sex'] = json_decode($data['sex'],true);
                echo '识别成功' . json_encode($data,JSON_UNESCAPED_UNICODE);
              }
            }
          }
        }
    拍照页面
    <view class='camera'>切换摄像头
      <view class='weui-cell_ft'>
              <switch checked bindchange='switch1Change'></switch>
      </view>
    </view>
     <view class='photo'>
        <camera device-position="{{camera}}" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
        <button type="primary" bindtap="takePhoto">拍照</button>
    </view>
    js
    // pages/camera/camera.js
    Page({
      data: {
        src: null
      },
      switch1Change: function (e) {
        if (e.detail.value) {
          this.setData({ camera: 'front' })
        } else {
          this.setData({ camera: 'back' })
        }
      },
      takePhoto() {
        const ctx = wx.createCameraContext()
        ctx.takePhoto({
          quality: 'high',
          success: (res) => {
            this.setData({
              src: res.tempImagePath
            })
            wx.uploadFile({
              url: 'http://****.top/program-php/server/index.php/home/index/login', //仅为示例,非真实的接口地址
              filePath: this.data.src,
              name: 'file',
              formData: {
              },
              success: function (res) {
                // var data = res.data
                console.log(res)
                wx.showModal({
                  title: '提示',
                  content: res.data,
                  showCancel:false,
                  confirmText:'确定'
                })
              }
            })
          }
        })
      },
      error(e) {
        console.log(e.detail)
      },
    在学生列表页面需要实现页面的下拉刷新和上拉加载功能
    onPullDownRefresh,页面相关事件处理函数--监听用户下拉动作
    onReachBottom,页面上拉触底事件的处理函数
    //获取应用实例
    const app = getApp()
    var page = 1;
    var isfinish = false;//加载完毕
    function loadmore(that){
      if(isfinish) return;
      wx.showLoading({
        title: '正在加载中',
      })
      wx.request({
        url: 'http://*****.top/program-php/server/index.php/home/index/select_index',
        data: {
          page:page,
          condition:that.data.condition
        },
        success: (res) => {
          console.log(res.data.data);
          var data =res.data.data;
          wx.hideLoading();
          if(data.length>0){
            var student=that.data.student;
            for(var i = 0;i<data.length;i++){
              student.push(data[i]);
            }
            that.setData({student:student});
            page++;
          }else{
            isfinish = true;
          }
          wx.stopPullDownRefresh();
        }
      })
    }
    Page({
      data: {
        student: [],
        inputShowed: false,
        inputVal: "",
        condition:''
      },
      //搜索框
      showInput: function () {
        this.setData({
          inputShowed: true
        });
      },
      hideInput: function () {
        this.setData({
          inputVal: "",
          inputShowed: false,
          condition:'',
          student:[]
        });
        page=1
        loadmore(this)
      },
      clearInput: function () {
        this.setData({
          inputVal: ""
        });
      },
      inputTyping: function (e) {
        this.setData({
          inputVal: e.detail.value
        });
      },
      onPullDownRefresh: function () {
       page = 1;
       isfinish = false;
       this.setData({ student: [] });
       loadmore(this);
      },
      onReachBottom: function () {
        var that = this;
        loadmore(that);
        console.log(page)
      },
      formSubmit:function(e){
        console.log(e.detail.value.condition);
        this.setData({condition:e.detail.value.condition});
        var that = this
        page = 1
        this.setData({student:[]})
        loadmore(that)
      },
      onShow: function(){
       loadmore(this)
      }
    })
    





    展开全文
  • 现在关于人脸识别的SDK其实有很多,诸如face++、百度大脑之类的,他们都为开发者免费提供人脸识别的接口。阿里也和face++合作,实现了支付宝的刷脸支付。 但是很遗憾,网上关于识别一段视频中的用户行为(诸如...
  • 现在关于人脸识别的SDK其实有很多,诸如face++、百度大脑之类的,他们都为开发者免费提供人脸识别的接口。阿里也和face++合作,实现了支付宝的刷脸支付。 但是很遗憾,网上关于识别一段视频中的用户行为(诸如摇...
  • 从去年开始自学前端,到今年的服务器的学习,也算是自己的一大进步了!这几天开始搭建小程序的服务器,琢磨了三天的`Nginx`中间消息插件,期间也是不...微信小程序也仅仅只有`websocket`协议的说明,但是已经不维护了!
  • 人脸识别在现在很多的项目中都有应用,最常见的就属此次315曝光的支付宝刷脸登录,当然支付宝也出来做了澄清,我们还是需要相信科技的.支付宝的刷脸可谓是相当成熟了.下面我们来简单的分析一下支付宝的刷脸登录流程. ...
  • 1月22日,ios微信推出7.0.3版,在app商店里更新日志只轻描淡写说了一句:本次更新:-解决了一些已知问题。没错,就是这一句。话越少,事越大,真正要搞事的人只做不说。笔者看来,这一句顶万句,长远看其意义甚至比...
  • 短短的国庆8天假期一眨眼就过去了,下次长假只有等到过年了,本宝宝不开心。既然已经开始工作了,就要好好多学习点新知识,来提高自己的代码能力,今天带大家去实现简易的选择城市界面,并且可以根据城市首字母或者...
  • 2019-06-02 21:31:57 ...近日,支付宝蜻蜓、微信青蛙以及人行牵头银联和各商业银行推进落地的刷脸支付系统陆续开始推向市场,笔者近期分别对相关产业各方采用的技术原理和基本概念进行了一些学习和研...
  • 仿微信表情图片

    2016-07-13 15:02:09
    所以我就在研究了一下即时通讯软件,最近一个礼拜的时间进度都堵在了表情模块这一部分,所以我就将自己这一个礼拜以来的相关问题进行一个总结,以便和大家分享讨论,这里先上效果图:实现最终效果我打算分为三步来写...
  • 2018年的时候,艺灵接单时搞过微信小程序。当时在写地址页时碰到了一个bug,主要是针对ios设备的。即:textarea有最小的padding且不可被设置。当时的解决方法是利用wx.getSystemInfo这个API获取设备信息,然后做...
  • 看完之后如有不懂,请看:关于人脸和指纹识别共同交流方案,也可以关注微信公众号:雄雄的小课堂,回复:人脸识别群获取群号,群内有直接可以运行的源码可供下载,人脸识别所需的软件群内也有!!! 人脸识别,...
  • 进入正题 1. PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template> ...img @click="callCamera" :src="headImgSrc" alt="摄像头"&...
  • 福利手慢无廖雪峰的大数据开发必备教程-Spark视频资料终于免费了!限额领取~今年不少人觉得职场晋升不那么顺畅,说是大环境所致,这也没错。但身边有些人,却在如此“艰难”的环境下,顺利...
  • 一、前言 本文是《人脸识别完整项目实战》系列博文第1部分,第2节《项目系统架构设计》,本章内容系统介绍:人脸系统系统的项目架构设计,包括:业务架构、技术架构、应用架构和数据架构四部分内容。...
1 2 3 4 5 ... 13
收藏数 241
精华内容 96
关键字:

微信开发能实现眨眼