随着人工智能和大数据分析技术越来越广泛,众多的生活场景都存在着这些技术的身影,比如像现在比较流行的人脸识别技术,其底层的算法实现的支撑,为众多的业务场景铺垫了基础,像支付宝的刷脸支付,本文是百度的人脸识别的微信小程序,后续出百度人脸识别的专题,下面开始项目的开发。
1.新建springboot项目
1.1首先引入百度人工智能的jar:
<!-- 百度人工智能 --><dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.4.1</version></dependency>
1.2案例使用fastjson,引入fastjson文件:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-json</artifactId></exclusion></exclusions></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency>
1.3获取所需的AppID、APIKey、SecretKey
访问网址:/,百度AI主页去注册一个百度账号,如果你有了百度云账号,可以直接进入到控制台里面去,创建一个应用,创建成功后,会分配给你一个应用信息,包含AppID ,API Key,Secret Key,这些是你调用人脸识别API的凭证,妥善保管
1.4新建REST风格的接口
package com.example.demo.controller;import com.alibaba.fastjson.JSONObject;import com.baidu.aip.face.AipFace;import com.baidu.aip.util.Base64Util;import lombok.var;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.multipart.MultipartHttpServletRequest;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.util.HashMap;@RestControllerpublic class UserController {static AipFace client = null;static {client = new AipFace(AppID, APIKey, SecretKey);// 可选:设置网络连接参数client.setConnectionTimeoutInMillis(2000);client.setSocketTimeoutInMillis(60000);}@PostMapping(value = "/face")public String faceDistinguish(HttpServletRequest request, HttpServletResponse response) throws Exception{MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;//对应前端的upload的name参数"file"MultipartFile multipartFile = req.getFile("file");try {return detectFace(multipartFile.getBytes(), "1");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}/*** 人脸检测** @return* @throws IOException*/public String detectFace(byte[] arg0, String max_face_num) {try {HashMap<String, String> options = new HashMap<String, String>();options.put("face_field", "age,beauty,expression,emotion,gender,glasses,race,qualities");options.put("max_face_num", "2");options.put("face_type", "LIVE");// 图片数据String imgStr = Base64Util.encode(arg0);String imageType = "BASE64";var res = client.detect(imgStr, imageType, options);JSONObject Jsonobject = new JSONObject();if(res.getInt("error_code")==0) {// 成功Jsonobject.put("code",0);var result = res.getJSONObject("result").getJSONArray("face_list").getJSONObject(0);//年龄Jsonobject.put("age", result.getInt("age"));//颜值Jsonobject.put("beauty", result.getDouble("beauty"));//表情//none:不笑;smile:微笑;laugh:大笑Jsonobject.put("expression", result.getJSONObject("expression").getString("type"));//性别//male:男性 female:女性Jsonobject.put("gender", result.getJSONObject("gender").getString("type"));//情绪//angry:愤怒 disgust:厌恶 fear:恐惧 happy:高兴 sad:伤心 surprise:惊讶 neutral:无表情 pouty: 撅嘴 grimace:鬼脸Jsonobject.put("emotion", result.getJSONObject("emotion").getString("type"));//眼镜//none:无眼镜,common:普通眼镜,sun:墨镜if(result.getJSONObject("glasses").getString("type").equals("none")){Jsonobject.put("glasses", "无眼镜");}else if(result.getJSONObject("glasses").getString("type").equals("common")){Jsonobject.put("glasses", "普通眼镜");}else{Jsonobject.put("glasses", "墨镜");}}else{//失败Jsonobject.put("code",1);Jsonobject.put("message",res.getString("error_msg"));}System.out.println(Jsonobject.toJSONString());return Jsonobject.toJSONString();} catch (Exception e) {e.printStackTrace();}return null;}private static byte[] FileToByte(File file) throws IOException {// 将数据转为流InputStream content = new FileInputStream(file);ByteArrayOutputStream swapStream = new ByteArrayOutputStream();byte[] buff = new byte[100];int rc = 0;while ((rc = content.read(buff, 0, 100)) > 0) {swapStream.write(buff, 0, rc);}// 获得二进制数组return swapStream.toByteArray();}}
1.5百度人脸识别返回的数据
检测失败:
{"result": null,"log_id": 594351565552,"error_msg": "pic not has face","cached": 0,"error_code": 222202,"timestamp": 1581855369}
检测成功:
{"result": {"face_num": 1,"face_list": [{"glasses": {"probability": 1,"type": "none"},"expression": {"probability": 0.78,"type": "smile"},"emotion": {"probability": 0.9,"type": "neutral"},"beauty": 71.92,"gender": {"probability": 1,"type": "female"},"race": {"probability": 1,"type": "yellow"},"angle": {"roll": -2.42,"pitch": 9.89,"yaw": -17.84},"face_token": "22c27c473034f97d6c9fd1e1739e62e5","location": {"top": 208.17,"left": 144.01,"rotation": -2,"width": 188,"height": 176},"face_probability": 1,"age": 17}]},"log_id": 655451589,"error_msg": "SUCCESS","cached": 0,"error_code": 0,"timestamp": 1581912291}
2.微信小程序开发
2.1修改app.js
修改其中的navigationBarTitleText,navigationBarBackgroundColor两个属性:
{"pages": ["pages/index/index"],"window": {"backgroundTextStyle": "light","navigationBarBackgroundColor": "#c9d0d8","navigationBarTitleText": "人脸检测","navigationBarTextStyle": "black"},"sitemapLocation": "sitemap.json"}
2.2index.wxml
<!--动画--><view class='animation' wx:if='{{animation}}'><view class='animation-list'></view></view><!--图片区域--><view class='pages'><view class='face'><image src='{{images}}' mode='widthFix'></image></view></view><!--识别结果--><view class='result'><text class='result-text'>识别结果</text></view><view wx:if='{{faceend}}'><view class='from'><text>性别</text><text>{{gender}}</text></view><view class='from'><text>年龄</text><text>{{age}}</text></view><view class='from'><text>表情</text><text>{{expression}}</text></view><view class='from'><text>颜值</text><text>{{beauty}}</text></view><view class='from'><text>情绪</text><text>{{emotion}}</text></view><view class='from'><text>眼镜</text><text>{{glasses}}</text></view></view><view wx:else>没有检查到人脸</view><view class='btn'><button type='primary' bindtap='faceImage'>选择图片</button></view>
2.3index.js
//index.js//获取应用实例const app = getApp()Page({data: {images:[],animation:false,//性别gender:'',//年龄age:'',//表情expression:'',//颜值beauty:'',//情绪emotion:'',//眼镜glasses:'',faceend:true},faceImage:function(){wx.chooseImage({count:1,sizeType:['original','compressed'],sourceType:['album','camera'],success: (res) => {var temFilePaths = res.tempFilePathsconsole.log(temFilePaths)this.setData({images: temFilePaths,animation:true})//像后台发送图片//延时返回数据setTimeout(()=>{wx.uploadFile({url: 'http://localhost:9900/face',filePath: temFilePaths[0],name: 'file',success: (res) => {var data = res.dataconsole.log(data)var datas = JSON.parse(data);if (datas.code == 1) {this.setData({faceend: false,animation:false})}else {this.setData({//性别gender: datas.gender,//年龄age: datas.age,//表情expression: datas.expression,//颜值beauty: datas.beauty,//情绪emotion: datas.emotion,//眼镜glasses: datas.glasses,faceend: true,animation:false});}}})},4000)},})}})
2.4index.wxss
.pages {background: #c9d0d8}.face {background: white;height: 500rpx;margin: 0 35rpx;text-align: center;overflow: hidden;}.face image {width: 500rpx;height:500rpx;}.result {background: white;padding: 25rpx;}.result-text {font-size: 30rpx;color: #00a4ff}.from{display:flex;padding:23rpx 25rpx;}.from text{font-size: 30rpx;margin-right: 20rpx;}.from:nth-child(odd){background: #f5f5f5;}.btn {position: fixed;bottom:5rpx;width: 100%;}.btn button {width: 450rpx;border-radius: 70rpx;}/* 动画 */.animation{position: fixed;top: 0;left: 0;right: 0;height: 500rpx;}.animation-list{width: 100%;height: 450rpx;background: linear-gradient(to bottom,rgba(216,179,255,0),rgba(216,179,255,1));position: relative;top: -600rpx;animation: myfist 2s linear 1s infinite alternate;}/* 开始执行动画 */@keyframes myfist {0%{background: linear-gradient(to bottom,rgba(216,179,255,0),rgba(216.179,255,1));left: 0;top: -600rpx;}25%{left: 0;top: 50rpx;}50%{left: 0;top: 50rpx;}75%{left: 0;top: 50rpx;}100%{left: 0;top: -600rpx;}}
2.5系统界面图
源码下载地址/download/u013938578/12163827