主要工作:
1、使用P
ostman工具模拟浏覽器發送請求,調用api的人臉檢測和人臉搜尋
2、根據api文檔,
封裝工具類為jar包,工具類中實作建立圖像集合,尋找圖檔,檢測人臉等操作,通過 靜态代碼塊實作
從properties配置檔案中讀取api的key和秘鑰以及人臉集合名稱
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIx0DciV2dmADM30zd-cmbw5ib1c0Y1dGROBTWE50MJRkT5BTeOlXW61EMrRVTyUEVOhXRE1EeJRUT5BzQOJTS650MJpWT2VERNhXSE1Ue4MkTykkeONTSq1kdjJjYzpkMMRXOykVdNNjW2hXbZVnTtx0dJRUT5N2ViBXO5xkNNh0YwIFSh9CXt92YuM3YltWas5iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
3、導入了
fastjson,用于将傳回的json字元串轉換為json對象
4、通過
servlet實作登入注冊,通過js
調用攝像頭,分别根據登入注冊按鈕使用ajxs執行相應操作
一、技術介紹
1、人臉識别
- face_token:當對一張圖檔進行人臉檢測時,會将檢測到的人臉記錄下來,包括人臉在圖檔中的位置,用一個系統辨別face_token來表示。
- 對同一張圖檔進行多次人臉檢測,對同一個人臉會得到不同的face_token。
- 人臉集合 faceSet:人臉集合(FaceSet)是用來存儲檢測到人臉的存儲對象。一個FaceSet内face_token是不重複的。
- 人臉搜尋:采集使用者新的人臉,在多個已知身份使用者的人臉集合中進行搜尋,找出新的人臉屬于哪一個已知身份使用者。人臉搜尋需要調用Search API。
2、接口介紹
使用了曠世公司的face plus plus提供的接口
https://www.faceplusplus.com/
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);
}
}
來自為知筆記(Wiz)