微信小程序开发实例——人脸识别开放平台

这篇具有很好参考价值的文章主要介绍了微信小程序开发实例——人脸识别开放平台。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

综述

之前我们有讲到在做一些深度学习图像算法开发时,为了更好的将算法效果展示出来,经常需要开发一些演示Demo应用,使用在线C/S交互式应用开发(类似于百度、腾讯、阿里的开放平台)。C代表Client(客户端),S代表Server(服务端),也就是UI处理与底层处理分离的方式,两端的连接交互媒介就是Http网络请求。像这里的算法演示在C端主要实现界面显示、交互、发送请求与图像绘制,S端主要是实现请求接收与返回、算法推理。C端主要包含移动端App/网页/小程序,S端就是后台算法运行服务器,本文主要介绍C端应用实例(微信小程序人脸识别开放平台)的开发。

条件准备

前面既然提到是C/S开放,那么这两者是缺一不可的。C就是我们本文要讲的,S代表后端服务,在这里主要实现的是人脸检测/五官定位/比对算法http请求接收接口,用以接收处理前端发来的算法请求。

服务器

请求地址:局域网/广域网

请求协议(可以根据需要自行定义)

以下是我自己定义的协议:

人脸检测请求协议
  Request:
  {
      "command": "detection",// 算法类型
      "image": imageBase64Str,// 待检测图片base64字符串码
      "max_face_num": 1,// 最大检测人脸数
      "image_url": "",// 待检测图片URL
      "face_attribute": 1,// 是否进行人脸属性检测
      "face_quality": 1// 是否进行人脸质量检测
  }
  Response:
  {
      "face_num": 1,//人脸个数
      "face_list": [
                      {
                          "location": {//人脸位置
                              "x1": 132,
                              "y1": 305,
                              "x2": 259,
                              "y2": 493
                          },
                          "score": 0.999789,
                          "attributes": {//人脸属性
                              "mask": 0,//是否戴口罩
                              "eyeopen": 1,//是否睁眼
                              "expression": 0,//是否正常表情
                              "yaw": 5,//偏转角
                              "pitch": 6,//俯仰角
                              "roll": 7//翻滚角
                          },
                          "quality": {
                              "brightness": 0,//亮度是否合格
                              "blur": 0,//清晰度是否合格
                              "occlusion": {//人脸7区域遮挡情况
                                  "left_eye": 1,
                                  "right_eye": 1,
                                  "nose": 1,
                                  "mouth": 1,
                                  "left_cheek": 1,
                                  "right_cheek": 1,
                                  "chin": 1
                              }
                          }
                      }
                  ],
    "request_id": "123456" //请求ID        
}
人脸五官定位请求协议
Request:
{
    "command": "landmark",// 算法类型
    "image": image base64,// 待检测图片base64字符串码
    "image_url": "",// 待检测图片URL
    "max_face": 1// 最大检测人脸数
}
Response
{
    "face_num": 1,//人脸个数
    "face_list": [
      {
        "landmark": [//人脸关键点坐标位置
          {
            "x": 50,
            "y": 108
          },
          {
            "x": 49,
            "y": 114
          },
          ......
          {
            "x": 71,
            "y": 111
          },
          {
            "x": 109,
            "y": 110
          }
        ]
      }
    ],
    "request_id": "123456"//请求ID
}
人脸比对请求协议
Request:
{
    "command": "compare",// 算法类型
    "image1": image base64,// 待检测图片1 base64字符串码
    "image2": image base64,// 待检测图片2 base64字符串码
    "image_url1": "",// 待检测图片1 URL
    "image_url2": "",// 待检测图片2 URL
    "quality_control": 0// 是否进行人脸质量控制
}
Response:
{
    "score": 99,//相似度分数(0~100)
    "request_id": "123456",//请求ID
    "error": 0 //错误码
}

以上三个条件可以自己搭建,也可以购买第三方的服务。

开发所用关键技术(接口)

图片文件选择与数据获取

我们在访问开放平台时经常需要找一些自己的图片进行测试,所以就需要这样一个方法来实现

如下代码:

wx.chooseImage({
    success: function(csi) {
        //获取图片缓存地址
        var tempFilePaths = csi.tempFilePaths
        imageUrl = tempFilePaths[0]
        //获取图片信息
        wx.getImageInfo({
            src: imageUrl,
            success (gii) {
                //根据图片拍摄方向获取图片的宽高
                if(gii.orientation=="up" || gii.orientation=="down" || gii.orientation=="up-mirrored" || gii.orientation=="down-mirrored"){
                    imageWidth = gii.width
                    imageHeight = gii.height
                }else{
                    imageWidth = gii.height
                    imageHeight = gii.width
                }
                //获取图片Base64码,一般网络请求发送的图片数据均是该格式数据
                let imageBase64 = wx.getFileSystemManager().readFileSync(imageUrl, "base64")
            }
        })
    }
})
图片算法处理网络请求

在获取到图片数据后,就需要将图片数据发送到后端进行算法处理请求来获取算法运行结果

如下代码:

wx.request({
    url: 'http://123.45.67.89:8080/face', //局域网接口地址(也可以是广域网/https地址)
    data: {
        "command": "detect",// 算法类型
        "image": imageBase64Str,// 待检测图片base64字符串码
        "max_face_num": 1,// 最大检测人脸数
        "image_url": "",// 待检测图片URL
        "face_attribute": 1,// 是否进行人脸属性检测
        "face_quality": 1// 是否进行人脸质量检测
    },
    header: {
        'content-type': 'application/json' // 请求头
    },
    method: "POST",// 请求方式
    timeout: 5000,// 请求超时
    dataType: "json",
    success (response) {
        // 请求成功处理
        // 打印返回结果
        console.log("face detect success:\n" + JSON.stringify(response, null ,2)) 
        ......
    },
    fail(res) {
        // 请求失败处理
        // 打印返回结果
        console.log("face detect fail:\n" + JSON.stringify(res, null ,2))
        //请求失败提示
        wx.showToast({
            title: '请求失败:' + res.errMsg,
            icon: 'none',
            duration: 2000
        })
    },
    complete(res) {
        // 请求完成处理
        console.log("face detect complete.")
    }
})
图片算法处理结果人脸框绘制

我们在拿到请求结果以后如果只是打印reponse数据并不能直观感受算法处理效果,这时如果能将结果通过图像绘制将人脸位置显示出来将是不错的处理方式

如下代码:

wx.createSelectorQuery()
    .select('#canvas_preview')//显示控件
    .fields({ node: true, size: true })
    .exec((scvs) => {
    // 获取控件像素尺寸
    const dom = scvs[0]
    const canvas = dom.node
    const ctx = canvas.getContext('2d')
    const dpr = wx.getSystemInfoSync().pixelRatio
    canvas.width = dom.width * dpr
    canvas.height = dom.height * dpr
    ctx.scale(dpr, dpr)
    const canvasMaxWidth = dom.width
    const canvasMaxHeight = dom.height
    // 获取图像缩放比例,保证图片在控件内完全显示
    const widthAdjustPara = canvasMaxWidth / imageWidth
    const heightAdjustPara = canvasMaxHeight / imageHeight
    var currentAdjustPara = 1
    if(widthAdjustPara<1 || heightAdjustPara<1) {
        currentAdjustPara = (widthAdjustPara <= heightAdjustPara ? widthAdjustPara : heightAdjustPara)
    }
    const canvasCurrentWidth = (currentAdjustPara===1 ? imageWidth : (imageWidth * currentAdjustPara))
    const canvasCurrentHeight = (currentAdjustPara===1 ? imageHeight : (imageHeight * currentAdjustPara))
    // 在控件内绘制原图
    var img =  canvas.createImage()
    img.src = imageUrl
    img.onload = function () {
        // 居中绘制
        ctx.drawImage(
            img, 
            (canvasMaxWidth-canvasCurrentWidth)/2 + 1, // image x start
            (canvasMaxHeight-canvasCurrentHeight)/2 + 1, // image y start
            canvasCurrentWidth, canvasCurrentHeight // image dst w, h
        )
        // 检测到人脸绘制人脸框(从返回数据reponseData中获取人脸框位置信息)
        if(isDetected){
            for (var i = 0; i < reponseData.data.face_num; i++) {
                var x1 = reponseData.data.face_list[i].location.x1
                var y1 = reponseData.data.face_list[i].location.y1
                var x2 = reponseData.data.face_list[i].location.x2
                var y2 = reponseData.data.face_list[i].location.y2
                ctx.strokeStyle = '#00e5ff' // 绘制线颜色
                // 矩形绘制
                ctx.rect(
                    (canvasMaxWidth-canvasCurrentWidth)/2 + x1 * currentAdjustPara, // rect left value
                    (canvasMaxHeight-canvasCurrentHeight)/2 + y1 * currentAdjustPara, // rect top value
                    (x2-x1) * currentAdjustPara, (y2-y1) * currentAdjustPara // rect w, h
                )
            }
            ctx.stroke()
        }
    }
})
图片算法处理结果人脸关键点绘制

我们在拿到请求结果以后如果只是打印reponse数据并不能直观感受算法处理效果,这时如果能将结果通过图像绘制将人脸关键点位置显示出来将是不错的处理方式

如下代码:

wx.createSelectorQuery()
    .select('#canvas_preview')//显示控件
    .fields({ node: true, size: true })
    .exec((scvs) => {
    // 获取控件像素尺寸
    const dom = scvs[0]
    const canvas = dom.node
    const ctx = canvas.getContext('2d')
    const dpr = wx.getSystemInfoSync().pixelRatio
    canvas.width = dom.width * dpr
    canvas.height = dom.height * dpr
    ctx.scale(dpr, dpr)
    const canvasMaxWidth = dom.width
    const canvasMaxHeight = dom.height
    // 获取图像缩放比例,保证图片在控件内完全显示
    const widthAdjustPara = canvasMaxWidth / imageWidth
    const heightAdjustPara = canvasMaxHeight / imageHeight
    var currentAdjustPara = 1
    if(widthAdjustPara<1 || heightAdjustPara<1) {
        currentAdjustPara = (widthAdjustPara <= heightAdjustPara ? widthAdjustPara : heightAdjustPara)
    }
    const canvasCurrentWidth = (currentAdjustPara===1 ? imageWidth : (imageWidth * currentAdjustPara))
    const canvasCurrentHeight = (currentAdjustPara===1 ? imageHeight : (imageHeight * currentAdjustPara))
    // 在控件内绘制原图
    var img =  canvas.createImage()
    img.src = imageUrl
    img.onload = function () {
        ctx.drawImage(
            img, 
            (canvasMaxWidth-canvasCurrentWidth)/2 + 1, // image x start
            (canvasMaxHeight-canvasCurrentHeight)/2 + 1, // image y start
            canvasCurrentWidth, canvasCurrentHeight // image dst w, h
        )
        // 检测到人脸绘制人脸关键点(从返回数据reponseData中获取人脸关键点位置信息)
        if(isDetected){
            var dot_radius = 1 //绘制点半径
            for (var i = 0; i < reponseData.data.face_num; i++) {
                var pointNum = reponseData.data.face_list[i].landmark.length
                for (var j = 0; j < pointNum; j++) {
                    var x = reponseData.data.face_list[i].landmark[j].x
                    var y = reponseData.data.face_list[i].landmark[j].y
                    ctx.beginPath()
                    ctx.fillStyle = "#00FFFF" // 绘制点颜色
                    // 圆点绘制
                    ctx.arc(
                        (canvasMaxWidth-canvasCurrentWidth)/2 + x * currentAdjustPara, 
                        (canvasMaxHeight-canvasCurrentHeight)/2 + y * currentAdjustPara, 
                        dot_radius, 0, 2 * Math.PI, true
                    )
                    ctx.closePath()
                    ctx.fill()
                } 
            }
        }
    }
})
图片算法处理结果人脸属性列表显示

我们在拿到请求结果以后如果只是打印reponse数据会显得比较乱,如果能通过列表整理的方式显示出来将是不错的选择

如下代码:

index.js

Page({
  data: {
    systemInfo: {}, // 界面信息
    isHiddenTable: false, //是否隐藏检测结果列表
    scrollToView: "0", //滑动控件位置
    resultListData:[], // 人脸检测结果列表
  },
  ......  
)
//拿到响应结果后的处理    
if(data.data.face_num===1){ //单人脸情况
    that.setData({
        userInfo:{
            tips:'单人脸检测结果'
        },
        isHiddenTable: false,//是否隐藏结果列表
        scrollToView: "单人脸检测结果",
        resultListData:[
            {"attribute":"坐标","valuetext":data.data.face_list[0].location.x1 + "  " 
             + data.data.face_list[0].location.y1 + "  " 
             + data.data.face_list[0].location.x2 + "  " 
             + data.data.face_list[0].location.y2
            },
            {"attribute":"口罩","valuetext":data.data.face_list[0].attributes.mask===0 ? "无" : "有"},
            {"attribute":"睁眼","valuetext":data.data.face_list[0].attributes.eyeopen===0 ? "否" : "是"},
            {"attribute":"表情","valuetext":data.data.face_list[0].attributes.expression===0 ? "正常" : "夸张"},
            {"attribute":"姿态","valuetext":data.data.face_list[0].attributes.yaw + "  "
             + data.data.face_list[0].attributes.pitch + "  "
             + data.data.face_list[0].attributes.roll
            },
            {"attribute":"亮度","valuetext":data.data.face_list[0].quality.brightness===0 ? "正常" : "异常"},
            {"attribute":"模糊","valuetext":data.data.face_list[0].quality.blur===0 ? "否" : "是"},
            {"attribute":"遮挡","valuetext":data.data.face_list[0].quality.occlusion.left_eye===0 
             && data.data.face_list[0].quality.occlusion.right_eye===0
             && data.data.face_list[0].quality.occlusion.nose===0
             && data.data.face_list[0].quality.occlusion.mouth===0
             && data.data.face_list[0].quality.occlusion.chin===0
             && data.data.face_list[0].quality.occlusion.left_cheek===0
             && data.data.face_list[0].quality.occlusion.right_cheek===0 ? "无" : "有"
            }
        ]
    })
}

index.wxml

<scroll-view class="userinfo-tips-scroll-view" style="width:{{canvasViewWidth}}px; height:{{canvasViewHeight/2}}px; display:flex; justify-content:center" scroll-y="true" scroll-top="{{scrollToView}}">
    <text class="userinfo-tips" style="display:flex; justify-content:center">{{userInfo.tips}}</text>
    <view class="table" hidden="{{isHiddenTable}}">
        <view class="tr bg-w">
            <view class="th">属性</view>
            <view class="th">结果值</view>
        </view>
        <block wx:for="{{resultListData}}" wx:key="{[attribute]}">
            <view class="tr bg-g" wx:if="{{index % 2 == 0}}">
                <view class="td">{{item.attribute}}</view>
                <view class="td">{{item.valuetext}}</view>
            </view>
            <view class="tr" wx:else>
                <view class="td">{{item.attribute}}</view>
                <view class="td">{{item.valuetext}}</view>
            </view>
        </block>
    </view>
</scroll-view>
功能切换导航栏定义

为了便于不同功能之间的切换演示,我们需要引入导航栏功能

如下代码:

index,js

Page({
  data: {
    systemInfo: {}, // 界面信息
    navbar: ['人脸检测', '人脸五官', '人脸比对'], // 功能界面选项列表
    currentNavbar: '0', //界面选项ID
    isHiddenTable: false, //是否隐藏检测结果列表
    scrollToView: "0", //滑动控件位置
    resultListData:[], // 人脸检测结果列表
    compareResultData:[], //人脸比对结果列表  
  }
......  
)

index.wxml文章来源地址https://www.toymoban.com/news/detail-789815.html

<!--index.wxml-->
<view class="navbar">
<!-- wx:for-index="idx" -->
  <view class="navbar-item" wx:for="{{navbar}}" wx:for-index="idx" data-idx="{{idx}}" bindtap="swichNav">
    <text class="navbar-text {{currentNavbar==idx ? 'active' : ''}}">{{item}}</text>
  </view>
</view>
<!-- 人脸检测功能栏 -->
<view class="hot-item-container {{currentNavbar==0 ? '' : 'hidden'}}">
<!-- 人脸检测主界面代码 -->
</view>
<!-- 人脸五官功能栏 -->
<view class="hot-item-container {{currentNavbar==1 ? '' : 'hidden'}}">
<!-- 人脸五官主界面代码 -->
</view>
<!-- 人脸比对功能栏 -->
<view class="hot-item-container {{currentNavbar==2 ? '' : 'hidden'}}">
<!-- 人脸比对主界面代码 -->
</view>

效果展示

微信小程序人脸识别,微信小程序,小程序,Powered by 金山文档
微信小程序人脸识别,微信小程序,小程序,Powered by 金山文档
微信小程序人脸识别,微信小程序,小程序,Powered by 金山文档

到了这里,关于微信小程序开发实例——人脸识别开放平台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序用什么工具开发(微信小程序开发工具介绍)

    有很多人在开发小程序之前都会去了解微信小程序开发工具,想知道微信小程序用什么工具开发。时至今日,随着互联网技术的发展,现在开发微信小程序也能使用多种不同的工具,让我们来了解一下吧。 一、微信开发者工具 这是微信官方提供的微信小程序开发工具,可以

    2024年02月11日
    浏览(67)
  • [微信小程序] 认识微信小程序及开发环境搭建

      微信公众平台首页 https://mp.weixin.qq.com   微信公众平台测试帐号系统 https://open.weixin.qq.com/connect/qrconnect?appid=wx39c379788eb1286ascope=snsapi_loginredirect_uri=http%3A%2F%2Fmp.weixin.qq.com%2Fdebug%2Fcgi-bin%2Fsandbox%3Ft%3Dsandbox%2Flogin   1、微信公众平台提供的帐号模式   2、各类型帐号的应用场景 餐厅

    2024年02月08日
    浏览(51)
  • uniapp调用微信小程序人脸识别步骤

    template script

    2024年02月16日
    浏览(40)
  • 【微信小程序】如何上传uniApp开发的微信小程序?

    微信开发者工具下载链接 Hbuilder X下载链接 扫码 选中账号 登录成功: ps: 如果之前没有权限但是已经登录此账号,需要在获取到权限后重新登录一次❗❗ ps: 不选中 运行时是否压缩代码 有可能代码包不包含插件大小过大,导致上传失败❗❗ 小程序性能优化指南 操作1 操作

    2024年02月09日
    浏览(216)
  • 微信小程序:实现微信小程序应用首页开发 (本地生活首页)

    小程序应用页面开发 1、创建项目并配置项目目录结构 创建项目我相信大家都会,不会的可以csdn搜索即可 这里我们需要对项目目录进行修改配置 在 app.json 文件中的 pages 数组中添加三个页面,如上图所示,然后我们将其他默认的两个进行删除,然后左侧目录 pages 文件夹中的

    2024年02月19日
    浏览(52)
  • 【微信小程序 | 实战开发】配置微信小程序APPID并快速接入

    你是否想要掌握人工智能的最新技术和应用?你是否想要成为未来社会的创新者和领导者?你是否想要和全球的优秀导师和同学一起学习和交流?如果你的答案是肯定的,那么欢迎来到床长人工智能教程网站,这里是你实现梦想的起点! 个人名片: 🐼 作者简介:一名大一在

    2024年01月24日
    浏览(65)
  • 微信小程序云开发

    1.小程序云开发,让前端程序员拥有后端的能力 2.包含:云函数(nodejs)、云数据库(mogodb)、云存储 3.前端写好函数-上传到云服务器 实现自定义云部署 4.前端去调用云函数,间接通过云函数对数据库的操作 5.前端-全栈 1.创建集合 2.添加记录   1.云id 来自云开发-概览-环境

    2024年02月04日
    浏览(44)
  • 前端开发——微信小程序

    使用的开发平台为——微信开发者工具(点击此处链接)  依次点击【工具】-【下载】-【稳定版更新日志】,找到适合的版本,进行下载安装。 注册微信小程序(点击注册链接),注意注册的是”小程序“。 根据注册提示完成后,进入以下界面: 在侧边栏点击【开发】-

    2024年02月03日
    浏览(52)
  • 微信小程序 - 云开发

    小程序·云开发是微信团队联合腾讯云推出的专业的小程序开发服务。 开发者可以使用云开发快速开发小程序、小游戏、公众号网页等,并且原生打通微信开放能力。 开发者无需搭建服务器,可免鉴权直接使用平台提供的API进行业务开发 小程序 云开发又简称tcb,是微信官方

    2024年04月08日
    浏览(49)
  • 微信小程序云开发|基于微信小程序实现房产中介平台系统

    作者主页:编程千纸鹤 作者简介:Java、前端、Python开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路  关注作者有好处 文末获得源码 项目编号:BS-XCX-012 语言环境:微信小程序 开发工具:微信开

    2024年04月25日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包