Java實現(xiàn)人臉識別登錄、注冊等功能(最新完整版)
前言:
這段時間由于學校實行靜態(tài)化管理,寢室門和校門都是用了人臉識別的裝置,每次經過都會激發(fā)我的好奇心,也想自己搞一個人臉識別玩玩,隨著開始查找資料來研究這方面的信息,還好有好幾家公司都有提供這方面的免費API,也是省下來很多功夫。一開始采用的是face++,但是在執(zhí)行到最后一步人臉搜索時出現(xiàn)問題,一直提示INVALID_OUTER_ID,跟著官方文檔,一步步抽離再封裝,最終還是以失敗告終,無奈只能選擇放棄。接著輾轉第二家 百度AI ,這次還是比較順利的,中間只出現(xiàn)過一次錯誤 ,而且官方大大還給出了解決方案,很是貼心,最終還是實現(xiàn)了開始的預想:成功使用人臉來實現(xiàn)注冊和登錄功能。
本系列項目從設計到實現(xiàn)源碼全部開源免費學習使用,一起追向理想,歡迎各位大佬監(jiān)督打卡開發(fā)!
難度分析:
由于使用的是百度云AI/face++這兩個平臺的現(xiàn)有的Api接口,所以分別對二者的難度進行分析介紹:
- face++
? 曠視face++的難度在于需要自己對官方提供的代碼段進行獨立封裝,這就比較考驗開發(fā)者的代碼抽取能力和 自我獨立封裝的技能,如果不能很好地進行抽取封裝,就會造成代碼的冗余以及內存的浪費,這樣封裝的效 果并不能達到最佳。比較耗費時間,在抽取face++平臺的代碼段時需要對IO流有著比較好的理解,從而讀取 讀取配置文件中的內容,這里就不多做介紹。
- 百度云AI
? 百度云AI可以讓開發(fā)者對開發(fā)難度有所選擇,因為該平臺提供了兩種方式:第一種方式類似于face++需要抽 取代碼然后進行代碼封裝,難度分析見上述face++對分析;第二種方式則是百度云提供了Maven倉庫,可以 直接導入依賴,直接調用相應的Api進行開發(fā)即可!有較好的選擇性!
前端使用JQuery調用本地攝像頭進行拍攝(自我感覺這是最難的部分)
項目回顧(百度云AI)
最終效果演示:

技術選型:
- SpringBoot
- BootStrap
- Thymeleaf
- 百度云AI / Face++
項目需求分析
為了用戶登錄的便捷,不再輸入賬號密碼進行手動登錄與注冊,而是使用JQuery調用本機的攝像頭進行拍攝照片,然后調用人臉識別接口將人臉信息自動注冊進所使用的平臺(百度云/Face++)后,用戶即可進行人臉掃描實現(xiàn)登錄操作。
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DMRfhF6Z-1652173334791)(/Users/wumao/Documents/Typora筆記/typora-user-images/image-20220510155115622.png)]](http://img.jbzj.com/file_images/article/202205/202205130822503.png)
項目搭建
1. 前期準備 ① 進入百度云的人臉識別控制臺
如果沒有百度賬號可以使用手機號快速進行注冊進入百度云AI控制臺
②創(chuàng)建人臉識別應用
【1】創(chuàng)建應用

【2】可以選擇自己想要使用的接口:比如人臉識別、語音技術等,本次項目采用的是人臉識別,官方也默認選擇了人臉識別的全部接口,所以也不需要做改動,只需要填寫應用名稱即可!

【3】獲取秘鑰

2. 測試百度云API
① 導入依賴
<dependency> <groupId>com.baidu.aip</groupId> <artifactId>java-sdk</artifactId> <version>4.9.0</version> </dependency>
② 測試部分API(人臉注冊、人臉檢測、人臉搜索等)
人臉注冊
用于從人臉庫中新增用戶,可以設定多個用戶所在組及組內用戶的人臉圖片
典型應用場景:構建屬于自己人臉庫,比如:會員人臉注冊、已有用戶補全人臉信息
測試代碼
//人臉注冊
@Test
public void testFaceRegister() throws IOException {
//1. 創(chuàng)建Java代碼和百度云交互的Client對象
AipFace client = new AipFace("AppId","Api_key","Api_secret");
//2. 參數(shù)設置(示例下表格對參數(shù)進行介紹)
HashMap<String,String> map = new HashMap<>();
map.put("quality_control","NORMAL");//圖片質量
map.put("liveness_control","LOW");//活體檢測
//3. 構造圖片
String path = "本地圖片路徑";
//上傳的圖片 兩種格式:url地址 Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//4.調用api方法完成人臉注冊
/**
* 參數(shù)1:圖片的url或者base64字符串
* 參數(shù)2:圖片形式(URL,BASE64)
* 參數(shù)3:組Id(固定一個字符串)
* 參數(shù)4:用戶Id
* 參數(shù)5:hashMap基本參數(shù)配置
*/
JSONObject res = client.addUser(encode, "BASE64", "pdx", "1000", map);
System.out.println(res.toString());
}
測試結果:只要最后error_code為0則表示測試成功,后續(xù)封裝代碼也是需要判斷error_code的值
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-noSP5q2r-1652173334793)(/Users/wumao/Documents/Typora筆記/typora-user-images/image-20220510141916574.png)]](http://img.jbzj.com/file_images/article/202205/202205130822507.png)
參數(shù)介紹:
| 參數(shù)名稱 | 是否必選 | 類型 | 默認值 | 說明 |
|---|---|---|---|---|
| image | 是 | String | 圖片信息(總數(shù)據(jù)大小應小于10M),圖片上傳方式根據(jù)image_type來判斷 | |
| image_type | 是 | String | 圖片類型BASE64:圖片的base64值,base64編碼后的圖片數(shù)據(jù),編碼后的圖片大小不超過2M;URL:圖片的 URL地址( 可能由于網絡等原因導致下載圖片時間過長);FACE_TOKEN: 人臉圖片的唯一標識,調用人臉檢測接口時,會為每個人臉圖片賦予一個唯一的FACE_TOKEN,同一張圖片多次檢測得到的FACE_TOKEN是同一個。 | |
| face_field | 否 | string | 包age,expression,face_shape,gender,glasses,landmark,landmark150,quality,eye_status,emotion,face_type,mask,spoofing信息逗號分隔. 默認只返回face_token、人臉框、概率和旋轉角度 | |
| max_face_num | 否 | uint32 | 最多處理人臉的數(shù)目,默認值為1,根據(jù)人臉檢測排序類型檢測圖片中排序第一的人臉(默認為人臉面積最大的人臉),最大值120 | |
| face_type | 否 | string | 人臉的類型LIVE表示生活照:通常為手機、相機拍攝的人像圖片、或從網絡獲取的人像圖片等 IDCARD表示身份證芯片照:二代身份證內置芯片中的人像照片WATERMARK表示帶水印證件照:一般為帶水印的小圖,如公安網小圖CERT表示證件照片:如拍攝的身份證、工卡、護照、學生證等證件圖片默認LIVE |
人臉檢測
判斷圖片是否具有面部信息
測試代碼
@Test
public void testFaceCheck() throws IOException {
//1. 創(chuàng)建Java代碼和百度云交互的Client對象
AipFace client = new AipFace("AppId","Api_key","Api_secret");
//2. 構造圖片
String path = "本地圖片路徑";
//上傳的圖片 兩種格式:url地址 Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//調用Api方法進行人臉檢測
/**
* 參數(shù)1:圖片的url或者base64字符串
* 參數(shù)2:圖片形式(URL,BASE64)
* 參數(shù)3:hashMap中的基本參數(shù)配置(null:使用默認配置)
*/
JSONObject res = client.detect(encode, "BASE64", null);
System.out.println(res.toString(2));
}測試結果:

參數(shù)介紹:
| 參數(shù)名稱 | 是否必選 | 類型 | 默認值 | 說明 |
|---|---|---|---|---|
| image | 是 | String | 圖片信息(總數(shù)據(jù)大小應小于10M),圖片上傳方式根據(jù)image_type來判斷 | |
| image_type | 是 | String | 圖片類型BASE64:圖片的base64值,base64編碼后的圖片數(shù)據(jù),編碼后的圖片大小不超過2M;URL:圖片的 URL地址( 可能由于網絡等原因導致下載圖片時間過長);FACE_TOKEN: 人臉圖片的唯一標識,調用人臉檢測接口時,會為每個人臉圖片賦予一個唯一的FACE_TOKEN,同一張圖片多次檢測得到的FACE_TOKEN是同一個。 | |
| face_field | 否 | string | 包age,expression,face_shape,gender,glasses,landmark,landmark150,quality,eye_status,emotion,face_type,mask,spoofing信息逗號分隔. 默認只返回face_token、人臉框、概率和旋轉角度 | |
| max_face_num | 否 | uint32 | 最多處理人臉的數(shù)目,默認值為1,根據(jù)人臉檢測排序類型檢測圖片中排序第一的人臉(默認為人臉面積最大的人臉),最大值120 | |
| face_type | 否 | string | 人臉的類型LIVE表示生活照:通常為手機、相機拍攝的人像圖片、或從網絡獲取的人像圖片等 IDCARD表示身份證芯片照:二代身份證內置芯片中的人像照片WATERMARK表示帶水印證件照:一般為帶水印的小圖,如公安網小圖CERT表示證件照片:如拍攝的身份證、工卡、護照、學生證等證件圖片默認LIVE |
人臉搜索
根據(jù)用戶上傳的圖片和指定人臉庫中的所有人臉進行比較,獲取相似度最高的一個或者某幾個的評分
返回值(數(shù)據(jù),只需要第一條,相似度最高的數(shù)據(jù))score:相似度評分(80分以上可以認為是同一個人)
測試代碼:
@Test
public void testFaceSearch() throws IOException {
//1. 創(chuàng)建Java代碼和百度云交互的Client對象
AipFace client = new AipFace("AppId","Api_key","Api_secret");
//2. 構造圖片
String path = "本地圖片路徑";
//上傳的圖片 兩種格式:url地址 Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//人臉搜索
JSONObject res = client.search(encode, "BASE64", "pdx", null);
System.out.println(res.toString(2));
}測試結果:

小結:
整體測試下來,和平常對數(shù)據(jù)庫的操作類似,都是增刪改查的操作,除了這些Api,還有其他的就不再贅述了,操作類似!所有測試代碼也會同項目案例一并上傳到Gitee倉庫中!
3. 搭建項目(使用Thymeleaf模板引擎)
① 創(chuàng)建Maven項目
引入相關依賴,構建所需文件目錄

② 編寫properties配置文件
ai.appId="api_id" ai.apiKey="api_key" ai.secretKey="api_secret" ai.imageType=BASE64 ai.groupId="自定義組" server.max-http-header-size=1000KB spring.thymeleaf.cache=false
③ 展示對上述部分Api接口進行二次封裝
private AipFace client;
private HashMap<String,String> map = new HashMap<>();
private BaiduAiUtils(){
map.put("quality_control","NORMAL");//圖片質量
map.put("liveness_control","LOW");//活體檢測
}
@PostConstruct
public void init(){
client = new AipFace(APP_ID,API_KEY,SECRET_KEY);
}
/**
* 人臉注冊,將用戶照片存入人臉庫中
* @param userId
* @param image
* @return
*/
public Boolean faceRegister(String userId,String image){
//人臉注冊
JSONObject res = client.addUser(image, IMAGE_TYPE, groupId, userId, map);
Integer errorCode = res.getInt("error_code");
return errorCode == 0? true : false;
}
/**
* 人臉更新,更新人臉庫中的用戶照片
* @param userId
* @param image
* @return
*/
public Boolean faceUpdate(String userId,String image){
//人臉更新
JSONObject res = client.updateUser(image, IMAGE_TYPE, groupId, userId, map);
Integer errorCode = res.getInt("error_code");
return errorCode == 0 ? true : false;
}
想要了解全部封裝代碼請移步Gittee倉庫
④ 編寫Controller前端控制器代碼
首選創(chuàng)建一個FaceLoginController類
跳轉到人臉登錄頁面的控制器
@RequestMapping("/")
public String toLogin(){
return "index";
}
實現(xiàn)人臉登錄邏輯
/**
* 人臉登錄
* @return
* @throws Exception
*/
@RequestMapping("/face-login")
@ResponseBody
public String searchface(@RequestBody @RequestParam(name = "imagebast64") StringBuffer imagebast64, HttpServletRequest request) throws Exception {
String userId = faceLoginService.loginByFace(imagebast64);
request.getSession().setAttribute("userId",userId);
request.getSession().setAttribute("username","派大星");
return userId;
}
實現(xiàn)人臉登錄業(yè)務邏輯層

由于在封裝接口時設定的imageType為Base64,所以在實現(xiàn)前端拍照時使用的是Canvas Api提供了toDataURL()方法將畫布中的圖形轉換為圖片,而默認情況下,toDataURL()方法把圖形轉變成Base64編碼格式的png,其格式為data:image/png;base64,xxxxx,而,后面的內容才是接口中需要的部分,所以需要對字符串進行切割處理。前端部分具體見下圖:

注意事項(項目搭建前了解)
① 出現(xiàn)qps不足如何解決
Open api qps request limit reached
這個問題官方也給出了具體的解決方案,在百度云控制臺可以免費領取測試額度,也是對開發(fā)者的一個福利。

此處貼上免費資源領取地址
② oauth 獲取錯誤
0 [main] WARN com.baidu.aip.client.BaseClient - oauth get error, current state: STATE_TRUE_CLOUD_USER
{
"error_msg": "IAM Certification failed",
"error_code": 14
}
具體原因:
仔細檢查:APP_ID、API_KEY、SECRET_KEY字符串中是否有空格
項目總結
使用百度云AI把項目整體搭建下來,可以很完美的實現(xiàn)最終的效果,人臉的識別速度也是相當迅速的,一些細節(jié)處理的特別到位,比如:在進行人臉識別的過程中眼睛必須對準攝像頭,當你的眼睛有所阻礙時,會提示的某眼處有阻礙等等。但是在并發(fā)方面支持的并不是很到位!
新鮮出爐的代碼將會及時更新到Gitee倉庫
以上代碼屬于部分實現(xiàn),想要了解完整版請移步派大星的Gitee倉庫
到此這篇關于Java實現(xiàn)人臉登錄、注冊等功能的文章就介紹到這了,更多相關Java人臉登錄、注冊內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring?boot前后端交互之數(shù)據(jù)格式轉換問題
這篇文章主要介紹了spring?boot前后端交互之數(shù)據(jù)格式轉換,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01
springboot集成mybatis?plus和dynamic-datasource注意事項說明
這篇文章主要介紹了springboot集成mybatis?plus和dynamic-datasource注意事項說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
Java 實戰(zhàn)項目錘煉之在線蛋糕商城系統(tǒng)的實現(xiàn)
讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+jdbc+mysql實現(xiàn)一個在線蛋糕商城系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11
Java?實現(xiàn)訂單未支付超時自動取消功能(京東商城為例)
本文以京東網上商城為例,給大家介紹商品在下單后沒有支付的情況下,超時自動取消功能,超過24小時,就會自動取消訂單,下面使用 Java 定時器實現(xiàn)超時取消訂單功能,感興趣的朋友一起看看吧2022-01-01
淺析JavaMail發(fā)送郵件后再通過JavaMail接收格式問題
這篇文章主要介紹了JavaMail發(fā)送郵件后再通過JavaMail接收格式問題 ,本文通過代碼實例給大家詳細解說,需要的朋友可以參考下2019-06-06
搭建Spring MVC和Vue3的應用程序的實現(xiàn)
本文主要介紹了搭建Spring MVC和Vue3的應用程序的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-11-11

