随着人工智能和大数据分析技术越来越广泛,众多的生活场景都存在着这些技术的身影,比如像现在比较流行的人脸识别技术,其底层的算法实现的支撑,为众多的业务场景铺垫了基础,像支付宝的刷脸支付,本文是百度的人脸识别的微信小程序,后续出百度人脸识别的专题,下面开始项目的开发。

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

访问网址:https://ai.baidu.com/,百度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;

@RestController
public 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 block
            e.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": 6520125451589,
  "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.tempFilePaths
        console.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.data
              console.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系统界面图

 

源码下载地址https://download.csdn.net/download/u013938578/12163827

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐