您的位置:首页 > 编程语言 > Java开发

[置顶] 【AI】Java+Fileupload+JSTL+Face++实现人脸识别系统

2017-09-14 15:46 1061 查看

一、前言

人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。

在现在我们的生活中,我们越来越多的接触到人工智能了。2016年3月,阿尔法围棋与围棋世界冠军、职业九段棋手李世石进行围棋人机大战,以4比1的总比分获胜;2016年末2017年初,该程序在中国棋类网站上以“大师”(Master)为注册帐号与中日韩数十位围棋高手进行快棋对决,连续60局无一败绩;2017年5月,在中国乌镇围棋峰会上,它与排名世界第一的世界围棋冠军柯洁对战,以3比0的总比分获胜。

小编从中感觉到了人工智能的第三次浪潮即将到来。随后小编最近研究了人工智能的人脸识别技术,刚开始研究了javacv、opencv,到现在研究的Face++,这个技术越来越成熟,也在不断的更新。下面带来人脸识别。

二、Face++介绍

Face++TM是新一代云端视觉服务平台,提供一整套世界领先的人脸检测,人脸识别,面部分析的视觉技术服务。网页地址请点直击

提供的技术包括了人脸检测、追踪、人脸关键点检测、 微笑分析、 性别、年龄、种族、1:1人脸验证、 1:N人脸识别、大规模人脸搜索。

小编亲测:上传狗或非人的照片,Face++是不会进行测试的。这个辩证的还是相当准确的,值得信赖。





三、实现过程

这里小编先说一下实现思路,小编把要解析的图片上传到服务器,然后通过调用face++的接口,对图片进行分析,得到分析的json数据。然后解析这些输入为中文,在界面显示分析结果。



3.0 项目环境要求

commons-io-2.5.jar

commons-fileupload-1.3.3.jar (用于上传图片)

net.sf.json jar (用于解析返回的Json)

jstl.jar

standard.jar (用于显示解析后的数据)

3.1 建立项目

建立一个java web项目:AresFace



3.2 上传图片:使用Apache的org.apache.commons.fileupload组件



上传图片前台代码:

核心就是一个提交表单,这个提交表单,要求为post,而且要enctype=”multipart/form-data”

然后方法提交到后台的UploadHandleServlet.java的servlet中,调用post方法,执行上传图片操作。

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="templatemo">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

<title>Stimulus HTML CSS Template</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/animate.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/font-awesome.min.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/templatemo-style.css">

<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700" rel="stylesheet">

</head>
<body data-spy="scroll" data-target=".navbar-collapse" data-offset="50">

${file}
${message}
<div class="preloader">
<div class="spinner">
<span class="spinner-rotate"></span>
</div>
</div>

<section id="contact" class="parallax-section">
<div class="container">
<div class="row">

<div class="col-md-6 col-sm-12">
<div class="contact-form">
<div class="wow fadeInUp section-title" data-wow-delay="0.2s">
<h1 class="color-white">Welcome to face recognition.</h1>
<p class="color-white">Author:Ares.</p>
</div>

<div id="contact-form">
<form action="${pageContext.request.contextPath}/servlet/UploadHandleServlet"" method="post" enctype="multipart/form-data" >
<div class="wow fadeInUp" data-wow-delay="1s">
<input name="username" type="text" class="form-control" id="fullname" placeholder="Your Name">
</div>
<!-- <div class="wow fadeInUp" data-wow-delay="1.2s">
<input name="email" type="email" class="form-control" id="email" placeholder="Your Email">
</div> -->
<!-- <div class="wow fadeInUp" data-wow-delay="1.4s">
<textarea name="message" rows="5" class="form-control" id="message" placeholder="Write your message..."></textarea>
</div> -->

<div class="wow fadeInUp" data-wow-delay="1.2s">
<input type="file" name="file1" class="form-control "/>
</div>

<div class="wow fadeInUp col-md-6 col-sm-8" data-wow-delay="1.4s">
<input name="submit" type="submit" class="form-control" id="submit" value="Send">
</div>
</form>
</div>

</div>
</div>

<div class="col-md-3 col-sm-6">
<div class="background-image contact-img" ></div>
<!--  <img alt="" src="images/contact-img.jpg" style="min-height: 75vh;" class="background-image ">  -->
</div>

<div class="bg-dark col-md-3 col-sm-6">
<div class="contact-thumb">
<div class="wow fadeInUp contact-info" data-wow-delay="0.6s">
<h3 class="color-white">Visit my office</h3>
<p> Zhi Sheng Chong off center four floor, Guangyang District , Langfang , China</p>
</div>

<div class="wow fadeInUp contact-info" data-wow-delay="0.8s">
<h3 class="color-white">Contact.</h3>
<p><i class="fa fa-phone"></i> 183-3360-2097</p>
<p><i class="fa fa-envelope-o"></i> <a href="mailto:18333602097@163.com">18333602097@163.com</a></p>
<p><i class="fa fa-globe"></i> <a href="http://blog.csdn.net/kisscatforever?viewmode=contents">www.Ares.com</a></p>
</div>

</div>
</div>

</div>
</div>
</section>

<!-- Footer Section -->
<footer style="background-position: 100% 106px;padding-top: 30px;">
<div class="container">
<div class="row">

<div class="col-md-12 col-sm-12">
<div class="wow fadeInUp footer-copyright" data-wow-delay="1.8s">
<p>Copyright © 2016 Your Company

| More Templates <a href="http://blog.csdn.net/kisscatforever?viewmode=contents" target="_blank" title="王雷">王雷@Ares.com</a> - Collect from <a href="http://blog.csdn.net/kisscatforever?viewmode=contents" title="技术天地" target="_blank">技术天地</a></p>
</div>
<ul class="wow fadeInUp social-icon" data-wow-delay="2s">
<li><a href="#" class="fa fa-facebook"></a></li>
<li><a href="#" class="fa fa-twitter"></a></li>
<li><a href="#" class="fa fa-google-plus"></a></li>
<li><a href="#" class="fa fa-dribbble"></a></li>
<li><a href="#" class="fa fa-linkedin"></a></li>
</ul>
</div>

</div>
</div>
</footer>

<!-- SCRIPTS -->

<script src="${pageContext.request.contextPath}/js/jquery.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script src="${pageContext.request.contextPath}/js/jquery.parallax.js"></script>
<script src="${pageContext.request.contextPath}/js/smoothscroll.js"></script>
<script src="${pageContext.request.contextPath}/js/wow.min.js"></script>
<script src="${pageContext.request.contextPath}/js/custom.js"></script>

</body>
</html>


UploadHandleServlet.java 上传图片并解析json数据

使用Apache文件上传组件处理文件上传步骤:

1、创建一个DiskFileItemFactory工厂

2、创建一个文件上传解析器

注意:解决上传文件名的中文乱码upload.setHeaderEncoding(“UTF-8”);

3、判断提交上来的数据是否是上传表单的数据

4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项

/**
* serlet 的post方法,用于上传图片和显示人脸分析后的信息
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
String savePath = this.getServletContext().getRealPath("/images");
File file = new File(savePath);
String filename = null;
List<Attributes> Attributeslist = new ArrayList<Attributes>();
// 判断上传文件的保存目录是否存在
if (!file.exists() && !file.isDirectory()) {
System.out.println(savePath + "目录不存在,需要创建");
// 创建目录
file.mkdir();
}
// 消息提示
String message = "";
try {
// 使用Apache文件上传组件处理文件上传步骤:
// 1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
// 解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
// 3、判断提交上来的数据是否是上传表单的数据
if (!ServletFileUpload.isMultipartContent(request)) {
// 按照传统方式获取数据
return;
}
// 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);
for (FileItem item : list) {
// 如果fileitem中封装的是普通输入项的数据
if (item.isFormField()) {
String name = item.getFieldName();
// 解决普通输入项的数据的中文乱码问题
String value = item.getString("UTF-8");
// value = new String(value.getBytes("iso8859-1"),"UTF-8");

System.out.println(name + "=" + value);
} else {// 如果fileitem中封装的是上传文件
// 得到上传的文件名称,
filename = item.getName();
System.out.println(filename);
if (filename == null || filename.trim().equals("")) {

continue;
}
// 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
// c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
// 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
filename = filename
.substring(filename.lastIndexOf("\\") + 1);
// 获取item中的上传文件的输入流
InputStream in = item.getInputStream();
// 创建一个文件输出流
FileOutputStream out = new FileOutputStream(savePath + "\\"
+ filename);
// 创建一个缓冲区
byte buffer[] = new byte[1024];
// 判断输入流中的数据是否已经读完的标识
int len = 0;
// 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while ((len = in.read(buffer)) > 0) {
// 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
// + filename)当中
out.write(buffer, 0, len);
}
// 关闭输入流
in.close();
// 关闭输出流
out.close();
// 删除处理文件上传时生成的临时文件
item.delete();

System.out.println("文件上传成功!");
}
}

//face++解析上传的图片,返回解析json数据
String faceMessage = FaceDetect
.getFaceMessage("D:/Ares/Java/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/AresFace/images/"
+ filename);

request.setAttribute("file", filename);
request.setAttribute("faceMessage", faceMessage);

// 使用 net.sf.json.JSONObject 解析json
JSONObject jsonObject = JSONObject.fromObject(faceMessage);

System.out.println("image_id:" + jsonObject.get("image_id"));
System.out.println("request_id:" + jsonObject.get("request_id"));
System.out.println("花费的时间:" + jsonObject.get("time_used") + "毫秒");
request.setAttribute("time_used",
"花费的时间:" + jsonObject.get("time_used") + "毫秒");

Attributeslist = JsontoList(faceMessage);

message = "人脸识别结果如下:";

request.setAttribute("message", message);
} catch (Exception e) {
message = "文件上传失败!";
e.printStackTrace();

}
request.setAttribute("AttributesList", Attributeslist);
// 信息界面显示
request.getRequestDispatcher("/message.jsp").forward(request, response);
}


3.3 使用face++提供的java类来获取解析后的图片的数据

建立类FaceDetect(face++提供的代码,需要用户注册先)

Face++官网:https://console.faceplusplus.com.cn/documents/6329752



这里需要说明的几点是:

1.方法参数:输入图片的url

2.注册Face++后的api_key和api_secret。

3.设置要显示的属性





建立FaceDetect类:

package com.dmsd.util;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import javax.net.ssl.SSLException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class FaceDetect {

/**
* 根据上传的图片路径获取face++解析的人脸信息
* @author Ares
* @param path 路径
* @return String
*/
public static String getFaceMessage(String path){
File file = new File(path);
byte[] buff = getBytesFromFile(file);
String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, byte[]> byteMap = new HashMap<String, byte[]>();
map.put("api_key", "Q01U_nrXThBS6zs-5dQ********JCcD");
map.put("api_secret", "U6h4ilxGtOjTeWjmF_jT********-IW");
map.put("return_attributes", "gender,age,smiling,headpose,emotion,ethnicity,beauty,mouthstatus,eyegaze");
byteMap.put("image_file", buff);

try{
byte[] bacd = post(url, map, byteMap);
String str = new String(bacd);
System.out.println(str);
return str;
}catch (Exception e) {
e.printStackTrace();
}
return "";
}

private final static int CONNECT_TIME_OUT = 30000;
private final static int READ_OUT_TIME = 50000;
private static String boundaryString = getBoundary();

/**
* 文件转换为二进制
* @author face++
* @param f 文件
* @return byte[] 二进制
*/
protected static byte[] post(String url, HashMap<String, String> map, HashMap<String, byte[]> fileMap) throws Exception {
HttpURLConnection conne;
URL url1 = new URL(url);
conne = (HttpURLConnection) url1.openConnection();
conne.setDoOutput(true);
conne.setUseCaches(false);
conne.setRequestMethod("POST");
conne.setConnectTimeout(CONNECT_TIME_OUT);
conne.setReadTimeout(READ_OUT_TIME);
conne.setRequestProperty("accept", "*/*");
conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
conne.setRequestProperty("connection", "Keep-Alive");
conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
DataOutputStream obos = new DataOutputStream(conne.getOutputStream());
Iterator iter = map.entrySet().iterator();
while(iter.hasNext()){
Map.Entry<String, String> entry = (Map.Entry) iter.next();
String key = entry.getKey();
String value = entry.getValue();
obos.writeBytes("--" + boundaryString + "\r\n");
obos.writeBytes("Content-Disposition: form-data; name=\"" + key
+ "\"\r\n");
obos.writeBytes("\r\n");
obos.writeBytes(value + "\r\n");
}
if(fileMap != null && fileMap.size() > 0){
Iterator fileIter = fileMap.entrySet().iterator();
while(fileIter.hasNext()){
Map.Entry<String, byte[]> fileEntry = (Map.Entry<String, byte[]>) fileIter.next();
obos.writeBytes("--" + boundaryString + "\r\n");
obos.writeBytes("Content-Disposition: form-data; name=\"" + fileEntry.getKey()
+ "\"; filename=\"" + encode(" ") + "\"\r\n");
obos.writeBytes("\r\n");
obos.write(fileEntry.getValue());
obos.writeBytes("\r\n");
}
}
obos.writeBytes("--" + boundaryString + "--" + "\r\n");
obos.writeBytes("\r\n");
obos.flush();
obos.close();
InputStream ins = null;
int code = conne.getResponseCode();
try{
if(code == 200){
ins = conne.getInputStream();
}else{
ins = conne.getErrorStream();
}
}catch (SSLException e){
e.printStackTrace();
return new byte[0];
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[4096];
int len;
while((len = ins.read(buff)) != -1){
baos.write(buff, 0, len);
}
byte[] bytes = baos.toByteArray();
ins.close();
return bytes;
}

/**
* 分割线
* @author face++
* @return
*/
private static String getBoundary() {
StringBuilder sb = new StringBuilder();
Random random = new Random();
for(int i = 0; i < 32; ++i) {
sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length())));
}
return sb.toString();
}
/**
* 设置编码格式
* @author face++
* @param value 传入的字符串
* @return String
* @throws Exception
*/
private static String encode(String value) throws Exception{
return URLEncoder.encode(value, "UTF-8");
}
/**
* 文件转换为二进制
* @author face++
* @param f 文件
* @return byte[] 二进制
*/
public static byte[] getBytesFromFile(File f) {
if (f == null) {
return null;
}
try {
FileInputStream stream = new FileInputStream(f);
ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = stream.read(b)) != -1)
out.write(b, 0, n);
stream.close();
out.close();
return out.toByteArray();
} catch (IOException e) {
}
return null;
}
}


得到的Json数据:

{
"image_id": "t5DgXIusFEBUtDMKQY4fQg==",
"request_id": "1505356245,91e741a5-2b4c-4c7c-af03-ec6e204546b4",
"time_used": 446,
"faces": [
{
"attributes": {
"emotion": {
"sadness": 0.057,
"neutral": 0.391,
"disgust": 70.593,
"anger": 0.653,
"surprise": 0.174,
"fear": 0.011,
"happiness": 28.121
},
"beauty": {
"female_score": 71.794,
"male_score": 69.887
},
"gender": {
"value": "Male"
},
"age": {
"value": 18
},
"mouthstatus": {
"close": 0,
"surgical_mask_or_respirator": 0,
"open": 100,
"other_occlusion": 0
},
"headpose": {
"yaw_angle": 6.347545,
"pitch_angle": 0.6853292,
"roll_angle": 10.896742
},
"smile": {
"threshold": 30.1,
"value": 27.335
},
"ethnicity": {
"value": "Asian"
},
"eyegaze": {
"right_eye_gaze": {
"position_x_coordinate": 0.535,
"vector_z_component": 0.913,
"vector_x_component": 0.087,
"vector_y_component": 0.399,
"position_y_coordinate": 0.448
},
"left_eye_gaze": {
"position_x_coordinate": 0.468,
"vector_z_component": 0.93,
"vector_x_component": -0.028,
"vector_y_component": 0.367,
"position_y_coordinate": 0.458
}
}
},
"face_rectangle": {
"width": 165,
"top": 478,
"left": 250,
"height": 165
},
"face_token": "4b6ad190af8778df2b96c74e8c84ad41"
},
{
"attributes": {
"emotion": {
"sadness": 21.467,
"neutral": 9.193,
"disgust": 5.763,
"anger": 0.226,
"surprise": 3.784,
"fear": 14.383,
"happiness": 45.183
},
"beauty": {
"female_score": 56.314,
"male_score": 55.251
},
"gender": {
"value": "Male"
},
"age": {
"value": 37
},
"mouthstatus": {
"close": 0,
"surgical_mask_or_respirator": 0,
"open": 100,
"other_occlusion": 0
},
"headpose": {
"yaw_angle": 0.013483647,
"pitch_angle": 2.941674,
"roll_angle": -1.834596
},
"smile": {
"threshold": 30.1,
"value": 58.645
},
"ethnicity": {
"value": "Asian"
},
"eyegaze": {
"right_eye_gaze": {
"position_x_coordinate": 0.482,
"vector_z_component": 0.94,
"vector_x_component": -0.045,
"vector_y_component": 0.337,
"position_y_coordinate": 0.364
},
"left_eye_gaze": {
"position_x_coordinate": 0.537,
"vector_z_component": 0.871,
"vector_x_component": 0.357,
"vector_y_component": 0.337,
"position_y_coordinate": 0.354
}
}
},
"face_rectangle": {
"width": 119,
"top": 376,
"left": 847,
"height": 119
},
"face_token": "471c6bda6c3f23dd721870897c63e9a8"
}
]
}


3.5 使用net.sf.json jar解析复杂的json

用json排版工具得到如下图:



解析方法:

/**
* 把face++返回的json转换为人脸属性对应的list集合
* @author Ares
* @param faceMessage face++返回的json
* @return List<Attributes>
*/
public List<Attributes> JsontoList(String faceMessage){
// 使用 net.sf.json.JSONObject 解析json
JSONObject jsonObject = JSONObject.fromObject(faceMessage);
List<Attributes> Attributeslist = new ArrayList<Attributes>();
try {
JSONArray facesArray = jsonObject.getJSONArray("faces");
JSONObject faces = null;

// 循环解析人脸属性特征的值
for (int i = 0; i < facesArray.size(); i++) {
faces = facesArray.getJSONObject(i);

/**
* 人脸属性特征
*   gender      --- 性别
*   age         --- 年龄
*   smiling     --- 笑容分析结果
*   headpose    --- 人脸姿势分析结果
*   eyestatus   --- 眼睛状态信息
*   emotion     --- 情绪识别结果
*   facequality --- 人脸质量判断结果
*   ethnicity   --- 人种分析结果
*   beauty      ---颜值识别结果
*   mouthstatus --- 嘴部状态信息
*   eyegaze     --- 眼球位置与视线方向信息
*/
JSONObject attributes = faces.getJSONObject("attributes");

JSONObject emotion = attributes.getJSONObject("emotion");
JSONObject beauty = attributes.getJSONObject("beauty");
JSONObject gender = attributes.getJSONObject("gender");
JSONObject age = attributes.getJSONObject("age");
JSONObject mouthstatus = attributes
.getJSONObject("mouthstatus");
JSONObject eyestatus = attributes.getJSONObject("eyestatus");
JSONObject smile = attributes.getJSONObject("smile");
JSONObject ethnicity = attributes.getJSONObject("ethnicity");
JSONObject eyegaze = attributes.getJSONObject("eyegaze");

JSONObject right_eye_gaze = eyegaze
.getJSONObject("right_eye_gaze");
JSONObject left_eye_gaze = eyegaze
.getJSONObject("left_eye_gaze");

// 把情绪存储到map中
Map<Double, String> emotionmap = new HashMap<Double, String>();
emotionmap.put((Double) emotion.get("anger"), "愤怒");
emotionmap.put((Double) emotion.get("disgust"), "厌恶");
emotionmap.put((Double) emotion.get("fear"), "恐惧");
emotionmap.put((Double) emotion.get("happiness"), "高兴");
emotionmap.put((Double) emotion.get("neutral"), "平静");
emotionmap.put((Double) emotion.get("sadness"), "伤心");
emotionmap.put((Double) emotion.get("surprise"), "惊讶");

Object[] obj = emotionmap.keySet().toArray();
Arrays.sort(obj);
System.out.println(obj[obj.length - 1]);

System.out.println("年龄:" + age.get("value"));
System.out.println("性别:" + gender.get("value"));
System.out.println("笑容值:" + smile.get("value") + " " + "笑容阈值:"
+ smile.get("threshold"));
System.out.println("情绪:" + emotionmap.get(obj[obj.length - 1])
+ " " + "" + obj[obj.length - 1]);
System.out.println("人种:" + ethnicity.get("value"));
System.out.println("颜值:" + beauty.get("female_score")
+ "(0~100越大颜值越高)");
Attributes ats = new Attributes();
ats.setAge("年龄:" + age.get("value"));
ats.setSmiling("笑容值:" + smile.get("value") + " " + "笑容阈值:"
+ smile.get("threshold"));
ats.setGender("性别:" + gender.get("value"));
ats.setEmotion("情绪:" + emotionmap.get(obj[obj.length - 1])
+ " " + "" + obj[obj.length - 1]);
ats.setEthnicity("人种:" + ethnicity.get("value"));
ats.setBeauty("颜值:" + beauty.get("female_score")
+ "(0~100越大颜值越高)");
ats.setFace_token("人脸标识face_token:" + faces.get("face_token"));
Attributeslist.add(ats);

/**
* 获取人脸矩形框的位置,包括以下属性。每个属性的值都是整数 top:矩形框左上角像素点的纵坐标
* left:矩形框左上角像素点的横坐标 width:矩形框的宽度 height:矩形框的高度
*/
JSONObject face_rectangle = faces
.getJSONObject("face_rectangle");
System.out
.println("矩形框左上角像素点的纵坐标:" + face_rectangle.get("top"));
System.out.println("矩形框左上角像素点的横坐标:"
+ face_rectangle.get("left"));
System.out.println("矩形框的宽度:" + face_rectangle.get("width"));
System.out.println("矩形框的高度:" + face_rectangle.get("height"));

/**
* 人脸的标识
*/
System.out.println("人脸标识face_token:" + faces.get("face_token"));
int j = i + 1;
System.out.println("--------------------------第" + j
+ "个人结束----------------------------");
}
} catch (Exception e) {
e.printStackTrace();
return null;
}

return Attributeslist;
}


解析后得到的数据:

image_id:t5DgXIusFEBUtDMKQY4fQg==
request_id:1505356245,91e741a5-2b4c-4c7c-af03-ec6e204546b4
花费的时间:446毫秒
70.593
年龄:18
性别:Male
笑容值:27.335 笑容阈值:30.1
情绪:厌恶 70.593
人种:Asian
颜值:71.794(0~100越大颜值越高)
矩形框左上角像素点的纵坐标:478
矩形框左上角像素点的横坐标:250
矩形框的宽度:165
矩形框的高度:165
人脸标识face_token:4b6ad190af8778df2b96c74e8c84ad41
--------------------------第1个人结束----------------------------
45.183
年龄:37
性别:Male
笑容值:58.645 笑容阈值:30.1
情绪:高兴 45.183
人种:Asian
颜值:56.314(0~100越大颜值越高)
矩形框左上角像素点的纵坐标:376
矩形框左上角像素点的横坐标:847
矩形框的宽度:119
矩形框的高度:119
人脸标识face_token:471c6bda6c3f23dd721870897c63e9a8
--------------------------第2个人结束----------------------------


3.5 显示人脸识别效果

展示图片,以及人脸识别分析结果:这里主要是利用了java表达式和jstl标准标签库来显示信息的。具体技术可以访问小编的另一系列博客:

【JSTL】JSP标准标签库

图片不错吧,每个程序员都有一个澎湃的内心。



前台代码:

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>消息提示</title>
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/css/font-awesome.min.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/css/main.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/css/animate.css" rel="stylesheet">
<link href="${pageContext.request.contextPath}/css/responsive.css" rel="stylesheet">
</head><!--/head-->

<body>

<section id="home">
<div id="main-slider" class="carousel slide" data-ride="carousel">

<div class="carousel-inner">
<div class="item active">
<img class="img-responsive" src="../images/${file}" alt="slider">
<div class="carousel-caption">
<h2>${message} </h2>
<c:forEach items="${AttributesList}" var="attributes" >
<h4> ${attributes.age}</h4>
<h4> ${attributes.gender}</h4>
<h4> ${attributes.smiling}</h4>
<h4> ${attributes.emotion}</h4>
<h4> ${attributes.ethnicity}</h4>
<h4> ${attributes.beauty}</h4>
<h4> ${attributes.face_token}</h4>
<br />
</c:forEach>
<h4> ${time_used}</h4>
<a href="${pageContext.request.contextPath}/AresFaceIndex.jsp">TEST ANGIN <i class="fa fa-angle-right"></i></a>
</div>
</div>

</div>
</div>
</section>

</body>
</html>


3.6 完成

到现在为止就完成了人脸识别,效果如下:



四、小结

通过这次系统研究,小编也是在其中学到了很多的东西,比如前提向后台servlet发送请求,后台sevlet接收参数,返回参数等。也用到了复杂Json解析,原来自己经常使用jackson来解析,但是这个的前提是要建立对应的类。从小编的json复杂程度来看,如果用Jacson的话,会建立很多的类的,所以小编就使用了其他的方法。

相信这一篇博客大家会受益匪浅,另外在下一篇的博客中,小编会向大家带来更精彩的人工智能,敬请期待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: