主要工作:
1、使用P
ostman工具模擬瀏覽器發送請求,調用api的人臉檢測和人臉搜索
2、根據api文檔,
封裝工具類為jar包,工具類中實現創建圖像集合,尋找圖片,檢測人臉等操作,通過 靜態代碼塊實現
從properties配置文件中讀取api的key和秘鑰以及人臉集合名稱

3、導入了
fastjson,用於將返回的json字符串轉換為json對象
4、通過
servlet實現登錄注冊,通過js
調用攝像頭,分別根據登錄注冊按鈕使用ajxs執行相應操作
一、技術介紹
1、人臉識別
- face_token:當對一張圖片進行人臉檢測時,會將檢測到的人臉記錄下來,包括人臉在圖片中的位置,用一個系統標識face_token來表示。
- 對同一張圖片進行多次人臉檢測,對同一個人臉會得到不同的face_token。
- 人臉集合 faceSet:人臉集合(FaceSet)是用來存儲檢測到人臉的存儲對象。一個FaceSet內face_token是不重復的。
- 人臉搜索:采集用戶新的人臉,在多個已知身份用戶的人臉集合中進行搜索,找出新的人臉屬於哪一個已知身份用戶。人臉搜索需要調用Search API。

2、接口介紹










postman工具可以模擬瀏覽器發送請求,提交數據


人臉檢測

人臉搜索

二、具體實現
1、根據API接口封裝的工具類的使用

工具類
package com.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.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class FaceUtil {
/**
* 根據傳入圖片進行人臉檢測
* @param file 傳入的人臉照片
* @return 返回人臉照片的facetoken,如果為空說明圖片不符合要求
* @throws Exception
*/
public static String detect(File file) throws Exception {
byte[] buff = HTTPUtil.getBytesFromFile(file);
String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
HashMap<String, byte[]> byteMap = new HashMap<>();
byteMap.put("image_file", buff);
byte[] bacd = HTTPUtil.post(url, HTTPUtil.map, byteMap);
String str = new String(bacd);
if(str.indexOf("error_message")!=-1) {
return null;
}
JSONObject obj = JSONObject.parseObject(str);
int faceNum=obj.getIntValue("face_num");
if(faceNum==1) {
//獲取facetoken
JSONObject face=(JSONObject) ((JSONArray)obj.get("faces")).get(0);
String faceToken=face.getString("face_token");
return faceToken;
}
return null;
}
/**
* 查詢指定的照片是否在人臉集合faceset中存在
* @param faceToken
* @return
* @throws Exception
*/
public static boolean search(String faceToken) throws Exception {
String url = "https://api-cn.faceplusplus.com/facepp/v3/search";
HTTPUtil.map.put("face_token", faceToken);
byte[] bacd = HTTPUtil.post(url, HTTPUtil.map, null);
String str = new String(bacd);
if(str.indexOf("error_message")==-1) {//請求沒有錯誤
JSONObject json = JSONObject.parseObject(str);
JSONObject thresholds=(JSONObject) json.get("thresholds");
Double le5=thresholds.getDouble("1e-5");
JSONArray results=(JSONArray) json.get("results");
if(results!=null && results.size()>=1) {
Double confidence=((JSONObject)results.get(0)).getDouble("confidence");
if(confidence>le5) {
return true;
}
}
}
return false;
}
/**
* 添加人臉到faceset中
* @param face_tokens 要添加的人臉
* @return
* @throws Exception
*/
public static boolean addFace(String face_tokens) throws Exception {
if(!getDetail()) {//先獲取人臉集合,沒有集合就創建一個
System.out.println("沒有獲取到指定人臉集合");
boolean res=createFaceSet();
if(!res) {
System.out.println("創建人臉集合出問題了!");
return false;
}
System.out.println("創建人臉集合成功!");
}
String url = "https://api-cn.faceplusplus.com/facepp/v3/faceset/addface";
HTTPUtil.map.put("face_tokens", face_tokens);
byte[] bacd = HTTPUtil.post(url, HTTPUtil.map, null);
String str = new String(bacd);
if(str.indexOf("error_message")!=-1) {
return false;
}
return true;
}
/**
* 創建一個人臉的集合 FaceSet,用於存儲人臉標識 face_token。
* @return
* @throws Exception
*/
public static boolean createFaceSet() throws Exception {
String url = "https://api-cn.faceplusplus.com/facepp/v3/faceset/create";
byte[] bacd = HTTPUtil.post(url, HTTPUtil.map, null);
String str = new String(bacd);
System.out.println(str);
if(str.indexOf("error_message")!=-1) {
return false;
}
System.out.println("創建人臉集合:"+str);
return true;
}
/**
* 獲取一個faceset
* @return
* @throws Exception
*/
public static boolean getDetail() throws Exception {
String url = "https://api-cn.faceplusplus.com/facepp/v3/faceset/getdetail";
byte[] bacd = HTTPUtil.post(url, HTTPUtil.map, null);
String str = new String(bacd);
if(str.indexOf("error_message")!=-1) {
return false;
}
return true;
}
}
2、測試類
package com.face.test;
import java.io.File;
import com.util.FaceUtil;
public class TestFace {
public static void main(String[] args) {
//獲取到要檢測的圖片
File file=new File("F:\\相冊\\微信圖片_20201217215617.jpg");
try {
String faceToken=FaceUtil.detect(file);
System.out.println("face_token:"+faceToken);//人臉的檢測
//添加一個人臉到集合中
boolean addFlag=FaceUtil.addFace(faceToken);//人臉的添加
System.out.println("添加成功:"+addFlag);
boolean flag=FaceUtil.search(faceToken);//人臉的搜索
System.out.println("人臉搜索的結果:"+flag);
//獲取人臉的集合
flag=FaceUtil.getDetail();
//如果沒有該集合,就創建 一個
if(!flag) {
flag=FaceUtil.createFaceSet();
System.out.println("如果沒有outer_id為JohnFaceSet的人臉集合,則創建一個新的!");
}
System.out.println("outer_id為JohnFaceSet的人臉集合:"+flag);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、登錄功能的實現
步驟分析


servlet:
- 概念: Servlet(Server Applet)是Java Servlet的簡稱,稱為小服務程序或服務連接器,用Java編 寫的服務器端程序,具有獨立於平台和協議的特性,主要功能在於交互式地瀏覽和生成數據,生成動態Web 內容。
- servlet任務
- 1)讀取客戶端(瀏覽器)發送的數據----(接受請求)
- 2) 處理數據並生成結果----(處理請求)
- 3)發送HTTP響應到客戶端(瀏覽器)----(給出響應)
package com.face.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.util.FaceUtil;
import com.wln.util.ImageUtils;
@WebServlet("/faceController")
//首字母要小寫
public class FaceController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* 1、接收用戶的請求request
* 2、處理請求
* 3、返回數據給客戶端response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//登錄的步驟
//1、獲取客戶上傳的圖片-上傳到指定的文件夾(upimg)
File file=ImageUtils.uploadImg(request, "imgData", "upimg");
boolean res=false;
//2、判斷是否包含人臉信息:detect
try {
String faceToken=FaceUtil.detect(file);
if(faceToken!=null) {
//2.1包含人臉
//在faceset中查找是否有相似度高的人臉信息search
res=FaceUtil.search(faceToken);
//有:登錄成功res=true;
//沒有:登錄失敗res=false;
}else {
//2.2不包含:登錄失敗
}
//刪除照片
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//刪除照片
file.delete();
//數據的返回 response返回數據給客戶端
PrintWriter pw=response.getWriter();
String msg="{\"success\":"+res+"}";
pw.write(msg);
pw.close();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
4、注冊功能的實現

package com.face.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.util.FaceUtil;
import com.wln.util.ImageUtils;
@WebServlet("/faceController")
//首字母要小寫
public class FaceController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* 1、接收用戶的請求request
* 2、處理請求
* 3、返回數據給客戶端response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//登錄的步驟
//1、獲取客戶上傳的圖片-上傳到指定的文件夾(upimg)
File file=ImageUtils.uploadImg(request, "imgData", "upimg");
boolean res=false;
boolean delFlag=true;
//2、判斷是否包含人臉信息:detect
try {
String faceToken=FaceUtil.detect(file);
if(faceToken!=null) {
//2.1包含人臉
//在faceset中查找是否有相似度高的人臉信息search
res=FaceUtil.search(faceToken);
//有:登錄成功res=true;
//沒有:登錄失敗res=false;
//判定用戶請求的類型
String type=request.getParameter("type");
if("register".equals(type)) {
if(res) {
//有,則已經注冊過
res=false;
//刪除照片
}else {
//沒有,可以注冊,添加facetoken到faceset中
res=FaceUtil.addFace(faceToken);
//保留照片
delFlag=false;
}
}
}else {
//2.2不包含:登錄失敗
}
//刪除照片
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//刪除照片
if(delFlag) {
file.delete();
}
//數據的返回 response返回數據給客戶端
PrintWriter pw=response.getWriter();
String msg="{\"success\":"+res+"}";
pw.write(msg);
pw.close();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}