來源: blog.csdn.net/Gaowumao?type=blog
想自己搞一個人臉識別玩玩,隨着開始查找資料來研究這方面的信息,還好有好幾家公司都有提供這方面的免費API,也是省下來很多功夫。一開始採用的是face++,但是在執行到最後一步人臉搜索時出現問題,一直提示INVALID_OUTER_ID,跟着官方文檔,一步步抽離再封裝,最終還是以失敗告終,無奈只能選擇放棄。
接着輾轉第二家 百度AI ,這次還是比較順利的,中間只出現過一次錯誤 ❌ ,而且官方大大還給出了解決方案,很是貼心,最終還是實現了開始的預想:成功使用人臉來實現註冊和登錄功能。
難度分析
由於使用的是百度雲AI/face++這兩個平台的現有的Api接口,所以分別對二者的難度進行分析介紹:
face++
曠視face++的難度在於需要自己對官方提供的代碼段進行獨立封裝,這就比較考驗開發者的代碼抽取能力和 自我獨立封裝的技能,如果不能很好地進行抽取封裝,就會造成代碼的冗餘以及內存的浪費,這樣封裝的效 果並不能達到最佳。比較耗費時間,在抽取face++平台的代碼段時需要對IO流有着比較好的理解,從而讀取 讀取配置文件中的內容,這裡就不多做介紹。
百度雲AI
百度雲AI可以讓開發者對開發難度有所選擇,因為該平台提供了兩種方式:第一種方式類似於face++需要抽 取代碼然後進行代碼封裝,難度分析見上述face++對分析;第二種方式則是百度雲提供了Maven倉庫,可以 直接導入依賴,直接調用相應的Api進行開發即可!有較好的選擇性!
前端使用JQuery調用本地攝像頭進行拍攝(自我感覺這是❗️❗️最難❗️❗️的部分)
項目回顧(百度雲AI) 最終效果演示:

技術選型:
SpringBoot
BootStrap
Thymeleaf
百度雲AI / Face++
項目需求分析
為了用戶登錄的便捷,不再輸入賬號密碼進行手動登錄與註冊,而是使用JQuery調用本機的攝像頭進行拍攝照片,然後調用人臉識別接口將人臉信息自動註冊進所使用的平台(百度雲/Face++)後,用戶即可進行人臉掃描實現登錄操作。

項目搭建1. 前期準備
① 進入百度雲的人臉識別控制台
如果沒有百度賬號可以使用手機號快速進行註冊進入百度雲AI控制台:
https://login.bce.baidu.com/?account=&redirect=http%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3F_%3D1652174073259%26fromai%3D1#/ai/face/overview/index
②創建人臉識別應用
【1】創建應用

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

【3】獲取秘鑰

2. 測試百度雲API
① 導入依賴
<dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.9.0</version></dependency>② 測試部分API(人臉註冊、人臉檢測、人臉搜索等)
人臉註冊
用於從人臉庫中新增用戶,可以設定多個用戶所在組及組內用戶的人臉圖片
典型應用場景:構建屬於自己人臉庫,比如:會員人臉註冊、已有用戶補全人臉信息
測試代碼
//人臉註冊@TestpublicvoidtestFaceRegister()throws IOException {//1. 創建Java代碼和百度雲交互的Client對象AipFace client = newAipFace("AppId","Api_key","Api_secret");//2. 參數設置(示例下表格對參數進行介紹)HashMap<String,String> map= newHashMap<>();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方法完成人臉註冊/*** 參數1:圖片的url或者base64字符串* 參數2:圖片形式(URL,BASE64)* 參數3:組Id(固定一個字符串)* 參數4:用戶Id* 參數5:hashMap基本參數配置*/JSONObject res = client.addUser(encode, "BASE64", "pdx", "1000", map);System.out.println(res.toString());}測試結果:只要最後error_code為0則表示測試成功,後續封裝代碼也是需要判斷error_code的值

人臉檢測
判斷圖片是否具有面部信息
測試代碼
@TestpublicvoidtestFaceCheck() throws IOException {//1. 創建Java代碼和百度雲交互的Client對象AipFace client = newAipFace("AppId","Api_key","Api_secret");//2. 構造圖片String path = "本地圖片路徑";//上傳的圖片 兩種格式:url地址 Base64字符串形式byte[] bytes = Files.readAllBytes(Paths.get(path));String encode = Base64Util.encode(bytes);//調用Api方法進行人臉檢測/*** 參數1:圖片的url或者base64字符串* 參數2:圖片形式(URL,BASE64)* 參數3:hashMap中的基本參數配置(null:使用默認配置)*/JSONObject res = client.detect(encode, "BASE64", null);System.out.println(res.toString(2));}測試結果:

人臉搜索
根據用戶上傳的圖片和指定人臉庫中的所有人臉進行比較,獲取相似度最高的一個或者某幾個的評分返回值(數據,只需要第一條,相似度最高的數據)score:相似度評分(80分以上可以認為是同一個人)
測試代碼:
@TestpublicvoidtestFaceSearch() throws IOException {//1. 創建Java代碼和百度雲交互的Client對象AipFace client = newAipFace("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));}測試結果:

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

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

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

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

此處貼上免費資源領取地址:https://login.bce.baidu.com/?account=&redirect=http%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3F_%3D1652277767387%26fromai%3D1#/ai/face/overview/resource/getFree
② oauth 獲取錯誤
0[main] WARN com.baidu.aip.client.BaseClient - oauth geterror, current state: STATE_TRUE_CLOUD_USER{"error_msg": "IAM Certification failed","error_code": 14}具體原因:
仔細檢查:APP_ID、API_KEY、SECRET_KEY字符串中是否有空格
項目總結
使用百度雲AI把項目整體搭建下來,可以很完美的實現最終的效果,人臉的識別速度也是相當迅速的,一些細節處理的特別到位,比如:在進行人臉識別的過程中眼睛必須對準攝像頭,當你的眼睛有所阻礙時,會提示的某眼處有阻礙等等。但是在並發方面支持的並不是很到位!
新鮮出爐的代碼將會及時更新到Gitee倉庫,以上代碼屬於部分實現,想要了解完整版請移步Gitee倉庫:
https://gitee.com/gao-wumao/ai-face-login