最新在写在一个web项目中加入人脸识别的功能的系统,在此我把相关的知识点做了个总结。
1.首先去Face++官网注册个账号,当然各个站点的人脸识别api大同小异。(Face++官网:https://www.faceplusplus.com.cn/)
2.注册完成后,创建一个试用的连接他们api的秘钥
具体步骤如下:
1.登进去后,进入如下页面,创建API Key:
2.接下来就是找到Api 引用的工具类了,具体图我就不贴了,找不到的话,直接引用我这个工具类就行了
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.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; import javax.net.ssl.SSLException; public class FaceTest { public static void main(String[] args) throws Exception{ File file = new File("你的本地图片路径"); byte[] buff = getBytesFromFile(file); String url = "https://api-cn.faceplusplus.com/facepp/v3/detect"; HashMapmap = new HashMap<>(); HashMap byteMap = new HashMap<>(); map.put("api_key", "你的KEY"); map.put("api_secret", "你的SECRET"); byteMap.put("image_file", buff); try{ byte[] bacd = post(url, map, byteMap); String str = new String(bacd); System.out.println(str); }catch (Exception e) { e.printStackTrace(); } } private final static int CONNECT_TIME_OUT = 30000; private final static int READ_OUT_TIME = 50000; private static String boundaryString = getBoundary(); protected static byte[] post(String url, HashMap map, HashMap 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 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 fileEntry = (Map.Entry ) 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; } 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(); } private static String encode(String value) throws Exception{ return URLEncoder.encode(value, "UTF-8"); } 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; } }
在web项目中引入了这个之后,要想进行人脸识别,就要看它的api了:
1.找到compare api这个功能就是做人脸对比的
2.读懂api
结合之前的工具类,在它的基础上进行修改
具体步骤不说了,应该都能看懂(注意必选项,一定要实现,四选一的只要选择其一就行,一定得选):
我把我的进行修改后的代码贴出来,大家就明白了,至于其他的功能比如证件识别,人体识别,都是在这个工具类的基础上进行修改。
这才是这篇文章的重点(在web项目中引入这个工具类就能进行人脸比对了,前面只是让大家了解怎么实现更多的功能):
//具体实现识别,只需要在service中或许是你的controller中要用FaceTest的compare方法就行,注意(在项目中导入fastjson.jar)
package cn.ljj.utils;
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.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import javax.net.ssl.SSLException;
import com.alibaba.fastjson.JSONObject;
//import com.alibaba.fastjson.JSONObject;
public class FaceTest {
public static Double compare(String url1,String url2) throws Exception{
File fiel1 = new File(url1);
File fiel2 = new File(url2);
//注意:这就是上面api提到的四选一其中的一个()
byte[] buff = getBytesFromFile(fiel1);
byte[] buff1 = getBytesFromFile(fiel2);
//注意url这个自己进api看下,是提供好的,其他所有的引用都要找到相对应的url
String url = "https://api-cn.faceplusplus.com/facepp/v3/compare";
HashMap map = new HashMap();
HashMap byteMap = new HashMap();
//必选项
map.put("api_key", "你的api key");
map.put("api_secret", "你的秘钥");
//注意
byteMap.put("image_file1", buff);
byteMap.put("image_file2", buff1);
//这里就是对返回值的设定,因为人脸识别主要看confidence值,而facequality的json串里,就包含了
//confidence,当然你还想获取其他的信息,请结合api,在这里做相应的配置
//这里就是你向face++提供的请求了
byte[] bacd = post(url, map, byteMap);
//返回值
String str = new String(bacd);
// System.out.println(str);
//这里就是对获取的返回值做解析了,将json串转换为jsonObject(请自行导入FastJson.jar)
JSONObject js = JSONObject.parseObject(str);
//利用FastJson提供的方法,取出相似值
String str1 =js.get("confidence").toString();
Double confidence = Double.parseDouble(str1);
System.out.println(str1);
//返回相似值,当相似值大于92,就认为是同一个人
return confidence;
}catch (Exception e) {
e.printStackTrace();
}
return 0;
}
private final static int CONNECT_TIME_OUT = 30000;
private final static int READ_OUT_TIME = 50000;
private static String boundaryString = getBoundary();
protected static byte[] post(String url, HashMap map, HashMap 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 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 fileEntry = (Map.Entry) 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;
}
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();
}
private static String encode(String value) throws Exception{
return URLEncoder.encode(value, "UTF-8");
}
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;
}
}