前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java 开发 face++ 人脸特征识别系统

java 开发 face++ 人脸特征识别系统

作者头像
Krry
发布2018-09-10 17:57:45
4.2K0
发布2018-09-10 17:57:45
举报
文章被收录于专栏:KrryblogKrryblog

首先要在 face++ 注册一个账号,并且创建一个应用,拿到 api key 和 api secret;

下载 java 接入工具,一个 jar 包:https://github.com/FacePlusPlus/java-sdk

请求返回的数据是 json 格式,需要导入 json 解析包:

commons-beanutils-1.8.3.jar commons-lang-2.5.jar commons-collections-3.2.2.jar ezmorph-1.0.6.jar json-lib-2.3-jdk15.jar

图片上传类:FileUpLoad.java

代码语言:javascript
复制
 1 package com.krry;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.util.List;
 8 import java.util.UUID;
 9 import javax.servlet.annotation.WebServlet;
10 import javax.servlet.http.HttpServlet;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 
14 import org.apache.commons.fileupload.FileItem;
15 import org.apache.commons.fileupload.FileItemFactory;
16 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
17 import org.apache.commons.fileupload.servlet.ServletFileUpload;
18 
19 /**
20  *  FileUpLoad
21  * @author krry
22  *
23  */
24 @WebServlet(name="fileUp",urlPatterns={"/show"})
25 public class FileUpLoad extends HttpServlet{
26     
27     private static final long serialVersionUID = 1L;
28 
29     @Override
30     public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
31         //判断是不是文件上传,根据请求包里面的内容是否为二进制提交的上传的文件 true/false
32         boolean isMultPart = ServletFileUpload.isMultipartContent(request);
33         if(isMultPart){
34             //创建文件上传工厂
35             FileOutputStream out = null;
36             InputStream in = null;
37             try {
38                  FileItemFactory factory = new DiskFileItemFactory();
39                  //创建容器文件类,负责处理上传的文件数据
40                 ServletFileUpload upload = new ServletFileUpload(factory);
41                  //解析上传文件,其实就是解析表单传过来的数据
42                 List<FileItem> fileItems = upload.parseRequest(request);
43                 //只需要拿一张图片
44                 in = fileItems.get(0).getInputStream();
45                 //获取源文件名
46                 String Ofilename = fileItems.get(0).getName();
47                 //拿到后缀名
48                 String ext = Ofilename.substring(Ofilename.indexOf("."), Ofilename.length());
49                 //拿到一个目录,绝对地址
50                 String path =request.getSession().getServletContext().getRealPath("/");
51                 //生成一个唯一的名字
52                 String fileName = UUID.randomUUID().toString() + ext;
53                 //定义上传目录
54                 String dirPath = path+"/upload";
55                 File dirFile = new File(dirPath);
56                 //如果此文件夹不存在
57                 if(!dirFile.exists()){
58                     dirFile.mkdirs();//创建此文件夹
59                 }
60                 //配置文件路径
61                 String filePath = path+"/upload/"+fileName;
62                 //输出流
63                 out = new FileOutputStream(filePath);
64                 //边读取边编写 字节流
65                 byte[] b = new byte[1024];
66                 int length = 0;
67                 while((length = in.read(b)) != -1){  //读到字节数组里面去
68                     out.write(b,0,length);   //从0开始写,写你读了多少
69                 }
70                 //放在request作用域里
71                 request.setAttribute("imgSrc", filePath);
72                 request.setAttribute("imgSrcPage", "upload/"+fileName);
73                 //请求转发,转发到另一个servlet
74                 request.getRequestDispatcher("showImage").forward(request, response);
75             } catch (Exception e) {
76                 
77                 e.printStackTrace();
78             }finally{
79                 out.close();
80                 in.close();
81             }
82         }
83     }
84 
85 }

人脸识别类:Analysis.java

这里返回一个 json 字符串,放到作用域,在前台获取

代码语言:javascript
复制
  1 package com.krry;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.DataOutputStream;
  5 import java.io.File;
  6 import java.io.FileInputStream;
  7 import java.io.IOException;
  8 import java.io.InputStream;
  9 import java.net.HttpURLConnection;
 10 import java.net.URL;
 11 import java.net.URLEncoder;
 12 import java.util.ArrayList;
 13 import java.util.Collections;
 14 import java.util.HashMap;
 15 import java.util.Iterator;
 16 import java.util.List;
 17 import java.util.Map;
 18 import java.util.Random;
 19 import java.util.TreeMap;
 20 
 21 import javax.net.ssl.SSLException;
 22 import javax.servlet.annotation.WebServlet;
 23 import javax.servlet.http.HttpServlet;
 24 import javax.servlet.http.HttpServletRequest;
 25 import javax.servlet.http.HttpServletResponse;
 26 
 27 import net.sf.json.JSONArray;
 28 import net.sf.json.JSONObject;
 29 
 30 /**
 31  *  analysis
 32  * @author krry
 33  * String 转json 需要的jar包:版本不能弄错
 34  * commons-beanutils-1.8.3.jar 
 35     commons-lang-2.5.jar
 36     commons-collections-3.2.2.jar
 37     ezmorph-1.0.6.jar 
 38     json-lib-2.3-jdk15.jar 
 39  */
 40 @WebServlet(name="analysis",urlPatterns={"/showImage"})
 41 public class Analysis extends HttpServlet{
 42     
 43     private static final long serialVersionUID = 1L;
 44     
 45     @Override
 46     public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
 47         
 48         //获取上传的图片地址
 49         String imgPath = request.getAttribute("imgSrc").toString();
 50         File file = new File(imgPath);
 51         byte[] buff = getBytesFromFile(file);
 52         String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
 53         HashMap<String, String> map = new HashMap<String, String>();
 54         HashMap<String, byte[]> byteMap = new HashMap<String, byte[]>();
 55         map.put("api_key", "15N9eBF_ieE-N2nvI7oK_A9anh2meuUS");
 56         map.put("api_secret", "cBnvsIAo8VaOj53lXCWlpuOSd0NrsFif");
 57         map.put("return_landmark", "1");
 58         map.put("return_attributes", "gender,age,smiling,headpose,facequality,blur,eyestatus,emotion,ethnicity,beauty,mouthstatus,eyegaze,skinstatus");
 59         byteMap.put("image_file", buff);
 60         try{
 61             byte[] bacd = post(url, map, byteMap);
 62             String str = new String(bacd);
 63             
 64             JSONObject json = JSONObject.fromObject(str);
 65             JSONArray faces = json.getJSONArray("faces");
 66             
 67             //解析失败
 68             if(str.indexOf("error_message") != -1 || faces.size() == 0){
 69                 request.getSession().setAttribute("error", "解析失败,请重新选择");
 70                 //重定向到首页
 71                 response.sendRedirect("index.jsp");
 72             }else{
 73                 //将人脸信息字符串str信息放到作用域
 74                 request.setAttribute("face", str);
 75                 //请求转发,返回到页面
 76                 request.getRequestDispatcher("showImage.jsp").forward(request, response);
 77             }
 78         }catch (Exception e) {
 79             e.printStackTrace();
 80         }
 81         
 82     }
 83     
 84     
 85     private final static int CONNECT_TIME_OUT = 30000;
 86     private final static int READ_OUT_TIME = 50000;
 87     private static String boundaryString = getBoundary();
 88     
 89     protected static byte[] post(String url, HashMap<String, String> map, HashMap<String, byte[]> fileMap) throws Exception {
 90         HttpURLConnection conne;
 91         URL url1 = new URL(url);
 92         conne = (HttpURLConnection) url1.openConnection();
 93         conne.setDoOutput(true);
 94         conne.setUseCaches(false);
 95         conne.setRequestMethod("POST");
 96         conne.setConnectTimeout(CONNECT_TIME_OUT);
 97         conne.setReadTimeout(READ_OUT_TIME);
 98         conne.setRequestProperty("accept", "*/*");
 99         conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
100         conne.setRequestProperty("connection", "Keep-Alive");
101         conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
102         DataOutputStream obos = new DataOutputStream(conne.getOutputStream());
103         Iterator iter = map.entrySet().iterator();
104         while(iter.hasNext()){
105             Map.Entry<String, String> entry = (Map.Entry) iter.next();
106             String key = entry.getKey();
107             String value = entry.getValue();
108             obos.writeBytes("--" + boundaryString + "\r\n");
109             obos.writeBytes("Content-Disposition: form-data; name=\"" + key
110                     + "\"\r\n");
111             obos.writeBytes("\r\n");
112             obos.writeBytes(value + "\r\n");
113         }
114         if(fileMap != null && fileMap.size() > 0){
115             Iterator fileIter = fileMap.entrySet().iterator();
116             while(fileIter.hasNext()){
117                 Map.Entry<String, byte[]> fileEntry = (Map.Entry<String, byte[]>) fileIter.next();
118                 obos.writeBytes("--" + boundaryString + "\r\n");
119                 obos.writeBytes("Content-Disposition: form-data; name=\"" + fileEntry.getKey()
120                         + "\"; filename=\"" + encode(" ") + "\"\r\n");
121                 obos.writeBytes("\r\n");
122                 obos.write(fileEntry.getValue());
123                 obos.writeBytes("\r\n");
124             }
125         }
126         obos.writeBytes("--" + boundaryString + "--" + "\r\n");
127         obos.writeBytes("\r\n");
128         obos.flush();
129         obos.close();
130         InputStream ins = null;
131         int code = conne.getResponseCode();
132         try{
133             if(code == 200){
134                 ins = conne.getInputStream();
135             }else{
136                 ins = conne.getErrorStream();
137             }
138         }catch (SSLException e){
139             e.printStackTrace();
140             return new byte[0];
141         }
142         ByteArrayOutputStream baos = new ByteArrayOutputStream();
143         byte[] buff = new byte[4096];
144         int len;
145         while((len = ins.read(buff)) != -1){
146             baos.write(buff, 0, len);
147         }
148         byte[] bytes = baos.toByteArray();
149         ins.close();
150         return bytes;
151     }
152     private static String getBoundary() {
153         StringBuilder sb = new StringBuilder();
154         Random random = new Random();
155         for(int i = 0; i < 32; ++i) {
156             sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length())));
157         }
158         return sb.toString();
159     }
160     private static String encode(String value) throws Exception{
161         return URLEncoder.encode(value, "UTF-8");
162     }
163     
164     public static byte[] getBytesFromFile(File f) {
165         if (f == null) {
166             return null;
167         }
168         try {
169             FileInputStream stream = new FileInputStream(f);
170             ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
171             byte[] b = new byte[1000];
172             int n;
173             while ((n = stream.read(b)) != -1)
174                 out.write(b, 0, n);
175             stream.close();
176             out.close();
177             return out.toByteArray();
178         } catch (IOException e) {
179         }
180         return null;
181     }
182     
183 
184 }

解析 json 字符串,先转换成 json 格式,json 数组,一个个获取人脸属性

代码语言:javascript
复制
  1 <%@page import="net.sf.json.JSONObject"%>
  2 <%@page import="net.sf.json.JSONArray"%>
  3 <%@ page language="java" import="java.io.File" pageEncoding="utf-8"%>
  4 <%@page import="java.math.BigDecimal"%>
  5 <%@ page import="java.util.*" %>
  6 <%
  7 
  8     String path = request.getContextPath();
  9     int port = request.getServerPort();
 10     String basePath = null; 
 11     if(port==80){
 12         basePath = request.getScheme()+"://"+request.getServerName()+path;
 13     }else{
 14         basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
 15     }
 16     pageContext.setAttribute("basePath", basePath);
 17     
 18     
 19     Object str = request.getAttribute("face");
 20     JSONObject json = JSONObject.fromObject(str);
 21     JSONArray faces = json.getJSONArray("faces");
 22     StringBuffer strBuff = new StringBuffer();
 23     //识别出人脸的个数
 24     int length = faces.size();
 25     
 26     //识别出多少个人脸,就是循环多少次
 27     for(int i = 0;i < length;i++){
 28     
 29         JSONObject face = faces.getJSONObject(i);  //拿到第i+1个人脸部信息
 30         JSONObject attribute = face.getJSONObject("attributes");//拿到脸部属性
 31         
 32         //年龄
 33         JSONObject age = attribute.getJSONObject("age");
 34         int ageValue = age.getInt("value");
 35         
 36         //性别
 37         JSONObject gender = attribute.getJSONObject("gender");
 38         String sex = gender.getString("value");
 39         if(sex.equals("Male")) sex = "男";
 40         else sex = "女";
 41         
 42         //人种
 43         JSONObject ethnicity = attribute.getJSONObject("ethnicity");
 44         String races = ethnicity.getString("value");
 45         if(races.equals("Asian")) races = "亚洲人";
 46         else if(races.equals("White")) races = "白人";
 47         else races = "黑人";
 48         
 49         //微笑程度
 50         JSONObject smile = attribute.getJSONObject("smile");
 51         String smileRange = String.format("%.2f",smile.getDouble("value"));
 52         
 53         //表情
 54         JSONObject emotion = attribute.getJSONObject("emotion");
 55         Map<String,Double> mapp = new TreeMap<String,Double>();
 56         //装配表情信息到map
 57         double sadness = emotion.getDouble("sadness");
 58         mapp.put("伤心", sadness);
 59         double neutral = emotion.getDouble("neutral");
 60         mapp.put("平静", neutral);
 61         double disgust = emotion.getDouble("disgust");
 62         mapp.put("厌恶", disgust);
 63         double anger = emotion.getDouble("anger");
 64         mapp.put("愤怒", anger);
 65         double happiness = emotion.getDouble("happiness");
 66         mapp.put("高兴", happiness);
 67         double surprise = emotion.getDouble("surprise");
 68         mapp.put("惊讶", surprise);
 69         double fear = emotion.getDouble("fear");
 70         mapp.put("恐惧", fear);
 71         
 72         //利用list取最大值
 73         List<Double> listmap = new ArrayList<Double>();
 74         for(String key:mapp.keySet()){
 75             listmap.add(mapp.get(key));
 76         }
 77         //取到最大值
 78         double valueMax = Collections.max(listmap);
 79         //根据map的value获取map的key  
 80         String emotionMax = "";  
 81         for (Map.Entry<String, Double> entry : mapp.entrySet()) {  
 82             if(valueMax == entry.getValue()){  
 83                 emotionMax = entry.getKey();  
 84             }
 85         }
 86         
 87         //颜值分数
 88         JSONObject beauty = attribute.getJSONObject("beauty");
 89         String beautys = "";
 90         if(sex.equals("男")) beautys = String.format("%.2f",beauty.getDouble("male_score"));
 91         else beautys = String.format("%.2f",beauty.getDouble("female_score"));
 92         
 93         //面部状态
 94         JSONObject skinstatus = attribute.getJSONObject("skinstatus");
 95         Map<String,String> mapSkin = new TreeMap<String,String>();
 96         //装配信息到map
 97         double health = skinstatus.getDouble("health");
 98         mapSkin.put("健康指数", String.format("%.2f",health));
 99         double stain = skinstatus.getDouble("stain");
100         mapSkin.put("色斑指数", String.format("%.2f",stain));
101         double acne = skinstatus.getDouble("acne");
102         mapSkin.put("青春痘指数", String.format("%.2f",acne));
103         double dark_circle = skinstatus.getDouble("dark_circle");
104         mapSkin.put("黑眼圈指数", String.format("%.2f",dark_circle));
105         
106         strBuff.append("<br>");
107         strBuff.append("<span>年龄:").append(ageValue).append("岁</span>");
108         strBuff.append("<span>性别:").append(sex).append("</span>");
109         strBuff.append("<br>").append("<br>");
110         strBuff.append("<span>人种:").append(races+"</span>");
111         strBuff.append("<span>微笑程度:").append(smileRange+"%</span>");
112         strBuff.append("<br>").append("<br>");
113         strBuff.append("<span>表情:").append(emotionMax+"</span>");
114         strBuff.append("<span>颜值分数:").append(beautys+"</span>");
115         strBuff.append("<br>").append("<br>");
116         int counts = 0;
117         for(String key:mapSkin.keySet()){
118             counts++;
119             strBuff.append("<span>"+key+":").append(mapSkin.get(key)+"</span>");
120             if(counts % 2 == 0) strBuff.append("<br>").append("<br>");
121         }
122              
123         strBuff.append("<br>");
124              
125     }
126       
127       
128 
129 %>
130 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
131 <html>
132   <head>
133     
134     <title> Java开发人脸特征识别系统  --krry</title>
135     
136     <meta http-equiv="pragma" content="no-cache">
137     <meta http-equiv="cache-control" content="no-cache">
138     <meta http-equiv="expires" content="0">    
139     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
140     <meta http-equiv="description" content="This is my page">
141 
142     <style type="text/css">
143          *{padding:0px;margin:0px;}
144          body{background: #FFF;background:url("images/78788.jpg");background-size:cover;}
145          .a_btn{text-decoration:none;font-family:"幼圆";background:#fff;transition:.6s;color:#f60;cursor:pointer;width:100px;height:40px;border-radius:10px;display: inline-block;text-align:center;line-height:40px;}
146         .aa{position: absolute;left: 48px;top: 31px;}
147         .a_btn:hover{background:red;color:#fff;transition:.6s;}
148          .clear{clear:both;}
149          .title{margin-top: 25px;font-size:48px;font-family:"幼圆";color: #ff7272;text-shadow: 1px 1px 3px #ff3737;text-align:center;line-height:45px;}
150          .content{margin:0 auto;width:900px;}
151           .content .img{float:left;margin-top:30px;}
152           .content .img img{border-radius:10px;}
153          .content .describe{margin-top:30px;width:500px;color:#000;font-family:"幼圆";font-size:18px;float:right;}
154          .content .describe span{width: 190px;display: inline-block;}
155     </style>
156 
157   </head>
158   
159   <body>
160           <div class="aa"><a class="a_btn" href="${basePath}">返回</a></div>
161           <div class="title">人脸识别结果</div>
162           <div class="content">
163             <div class = "img">
164                <img style="float:left" width="350" src="${imgSrcPage}" />
165             </div>
166             <div style="float:right" class="describe"><%=strBuff.toString() %></div>
167             <div class="clear"></div>
168         </div>
169   </body>
170 </html>

首页:

代码语言:javascript
复制
 1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
 2 
 3 <%
 4 
 5     Object ermsg = request.getSession().getAttribute("error");
 6     StringBuffer strBuff = new StringBuffer();
 7     if(ermsg != null){
 8         //清除作用域
 9         request.getSession().removeAttribute("error");
10         strBuff.append("loading('"+ermsg+"',4)");
11     }
12 %>
13 
14 <!doctype html>
15 <html>
16     <head>
17        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
18        <meta name="keywords" content="关键词,关键词">
19        <meta name="description" content="">
20        <link rel="stylesheet" type="text/css" href="css/sg.css" />
21        <link rel="stylesheet" type="text/css" href="css/sg/css/animate.css" />
22        <link rel="stylesheet" type="text/css" href="css/sg/css/sg.css" />
23        
24        <title> Java开发人脸特征识别系统  --krry</title>
25        <style type="text/css">
26            *{padding:0px;margin:0px;}
27            body{background:url("images/5.jpg");background-size:cover;font-size:18px;font-family:"微软雅黑";color:#666;}
28            img{border:none;}
29            h1{font-size:24px;}
30            .title{margin-top: 30px;font-size:48px;font-family:"幼圆";color: #ff7272;text-shadow: 1px 1px 3px #ff3737;text-align:center;line-height:45px;}
31            .box{margin:100px auto;text-align:center;}
32            .box .b_btn{width:100px;height:40px;background:#fff;transition:.6s;font-size:16px;font-family:"微软雅黑";display:block;margin:54px auto;text-align:center;
33                        cursor:pointer;line-height:40px;text-decoration:none;color:#F60;border:1px;border-radius:12px}
34               .box .b_btn:hover{background:red;color:#fff;transition:.6s;}
35               .busbu{top:0;background:rgba(0, 0, 0, 0.2);display:none;width:100%;height:100%;position:absolute;z-index:1000;}
36        </style>
37     </head>
38 
39 <body>
40    <!--action  提交的路径  method:post(打包传输) get(明文传输) enctype(采用二进制)-->
41    <form action="show" method="post" enctype="multipart/form-data">
42    <div class="box">
43        <div class="title">人脸特征识别系统 --krry</div>
44        <input type="file" id="fileChoice" accept="image/jpeg,image/png" style="display:none" name="files"/>
45        <a class="b_btn" href="javascript:void(0);" onclick="choice()">选择照片</a>
46        <input type="button" value="提交解析" class="b_btn" id="but"/>
47        <input type="submit" class="sub_btn" style="display:none;"/> 
48    </div>
49    </form>
50    <div class="busbu"></div>
51      <script src="js/jquery-1.11.3.min.js"></script>
52     <script src="js/sg.js"></script>
53     <script src="js/sgutil.js"></script>
54     <script type="text/javascript" src="css/sg/tz_util.js"></script>
55     <script type="text/javascript" src="css/sg/sg.js"></script>
56     <script type="text/javascript">
57     <%=strBuff.toString() %>
58     //选择照片
59     function choice(){
60        //js 弱类型  快速定位
61        var choose = document.getElementById("fileChoice");
62        choose.click();
63     }
64     $("#but").click(function(){
65         if($("#fileChoice").val()){//如果选择了照片
66             $(".sub_btn").click();
67             $(".busbu").show();
68             loading("正在解析",900);//再展示
69         }else{
70             $.tmDialog.alert({open:"top",content:"请先选择一张照片",title:"Krry温馨提醒"});
71         }
72     });
73       
74 </script>
75 </body>
76 
77 </html>

需要注意的点,json 字符串的转换和解析,获取 json 中人脸属性的方法 

git:https://github.com/Krryxa/face

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档