java 开发 face++ 人脸特征识别系统
Posted 艾涵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 开发 face++ 人脸特征识别系统相关的知识,希望对你有一定的参考价值。
首先要在 face++ 注册一个账号,并且创建一个应用,拿到 api key 和 api secret;
下载 java 接入工具,一个 jar 包:https://github.com/FacePlusPlus/facepp-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
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 字符串,放到作用域,在前台获取
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 数组,一个个获取人脸属性
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 =用Python做一个人脸识别系统,简单操作又实用~Java 离线人脸识别 基于ArcFace 2.0 Demo