如何從零搭建一個人臉識別應用?不妨試試原生Java人工智能算法:EasyAi + Milvus 的組合拳。
本文將使用到的軟件和工具包括:
EasyAi:人臉特征向量提取
Milvus:向量數據庫用于高效存儲和檢索數據。
01.
EasyAi:國內人氣最高的Java人工智能算法框架
作為純java開發 Ai 應用的框架,EasyAi無任何依賴,它是一個原生Java人工智能算法框架。首先,它可以Maven一鍵絲滑引入我們的Java項目,無需任何額外的環境配置與依賴,做到開箱即用。再者,它既有一些我們已經封裝好的圖像目標檢測及人工智能客服的模塊,也提供各種深度學習,機器學習,強化學習,啟發式學習,矩陣運算,求導函數,求偏導函數等底層算法工具。開發者可以通過簡單的學習,就能完成根據自身業務,深度開發符合自己業務的小微模型。
02.
EasyAi-Face:基于Easy-Ai的人臉識別應用
一,生成人類平均臉,將所有人臉樣本樣本縮放到統一尺寸后,多余的上下截斷,不足的進行補0,所有像素通道求和后獲取平均數,將樣本輸出生成平均臉。
二,通過事先訓練好的人臉定位fastYolo模型,對目標照片進行一次定位,并設置一個閾值,只有當可信度超過該閾值時才被認為是人臉。
三,獲取目標照片中可信度最高的人臉定位框,基于該定位進行人臉位置的二次修正。
二次修正方案:
通過粒子群,設置四個特征維度尋求最優解,它們分別是人臉位置左上角的x與y坐標與寬高。自適應函數返回值設置為最小值最優。xy與寬高四維粒子調整活動范圍,上下限制為一次定位坐標與寬高的+-50像素的范圍(自行可調)。
適應函數計算流程為通過四個維度粒子鎖定的坐標將人臉截取下來,將它與先前獲取的平均臉按照之前的縮放方案,再次縮放到指定的一個更小的尺寸,并將它們的灰度通道通過softMax將整個矩陣的所有數值概率化。
對比平均臉與粒子此時鎖定人臉灰度概率圖像的歐式距離,并返回。讓粒子探索(在指定迭代次數中)最小值最優解。
四,獲取人臉特征,獲取最后粒子尋找的最優坐標,根據該坐標將圖像截取下來,并截取其從上到下高度的0.7倍的圖像位置(將嘴部扔掉,嘴部的穩定性比較差),獲取此時圖像的LBP局部二值化紋理特征。
03.
EasyAi-Face + Milvus搭建人臉識別應用
3.1 提取人臉特征
引入依賴
<dependency><groupId>org.dromara.easyai</groupId><artifactId>seeFace</artifactId><version>1.0.5</version></dependency>
初始化Face
@Beanpublic?Face?face(FaceConfig?faceConfig?){if?(StringUtils.isNotBlank(faceConfig.getAvgFace())?&&?StringUtils.isNotBlank(faceConfig.getFaceModel())){return?FaceFactory.getFace(faceConfig.getAvgFace(),?faceConfig.getFaceModel());}return?FaceFactory.getFace();}
提取人臉特征
private?List<Float>?getFloats(InputStream?inputStream)?{ThreeChannelMatrix?m?=?Picture.getThreeMatrix(inputStream,?false);ErrorMessage?errorMessage?=?face.look(m,?idWorker.nextId(),?30);final?Matrix?feature?=?errorMessage.getFaceMessage().getFeature();return?MatrixUtil.matrixToFloatList(feature);}
3.2 存到向量庫
public?void?initUserVector(UserDTO?userDTO,?List<Float>?features)?{List<String>?names?=?Collections.singletonList(userDTO.getUserName());List<Long>?userIds?=?Collections.singletonList(userDTO.getUserId());List<String>?getFaceUrl?=?Collections.singletonList(userDTO.getFaceUrl());List<String>?getFaceFeatureUrl?=?Collections.singletonList(userDTO.getFaceFeatureUrl());List<List<Float>>?vectors?=?Collections.singletonList(features);List<Field>?fields?=?new?ArrayList();fields.add(new?Field("vector",?vectors));fields.add(new?Field("face_url",?getFaceUrl));fields.add(new?Field("face_feature_url",?getFaceFeatureUrl));fields.add(new?Field("user_id",?userIds));fields.add(new?Field("user_name",?names));InsertParam?insertParam?=?InsertParam.newBuilder().withCollectionName(milvusConfig.getCollectionName()).withFields(fields).build();this.milvusClient.insert(insertParam);}
3.3 【識別人臉】人臉特征L2相似性查找
public?List<UserDTO>?search(List<Float>?floatList,?Integer?topK)?{final?List<SearchResultsWrapper.IDScore>?idScoreList?=?vectorService.search(floatList,?topK);List<UserDTO>?list?=?new?ArrayList<>();idScoreList.forEach(idScore?->?{UserDTO?imageDTO?=?new?UserDTO();final?float?score?=?idScore.getScore();final?Map<String,?Object>?fieldValues?=?idScore.getFieldValues();imageDTO.setAutoId(Long.valueOf(String.valueOf(?fieldValues.getOrDefault("Auto_id",?"-1"))));imageDTO.setUserId(Long.valueOf(String.valueOf(?fieldValues.getOrDefault("user_id",?"-1"))));imageDTO.setUserName(String.valueOf((fieldValues.getOrDefault("user_name",?""))));imageDTO.setFaceUrl(String.valueOf((fieldValues.getOrDefault("face_url",?""))));imageDTO.setFaceFeatureUrl(String.valueOf((fieldValues.getOrDefault("face_feature_url",?""))));imageDTO.setScore(Math.sqrt(score));list.add(imageDTO);});return?list;}
04.
總結
本文展示了如何使用 EasyAi 和 Milvus 搭建一個人臉識別應用。通過結合Java生態EasyAi和Milvus向量搜索的優勢,我們可以快速的使用java搭建自己的人臉識別的項目。我們希望這篇文章對您有所幫助。同時,我們鼓勵您在自己的項目中使用EasyAi和向量搜索,探索更多可能性。本文涉及的代碼可以通過 Gitee 獲取:Easy-Ai-Face(https://gitee.com/fushoujiang/easy-ai-face)。
推薦閱讀