生活随笔
收集整理的這篇文章主要介紹了
人脸识别SDK调用与分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
該demo時是基于springboot的人臉識別和后期判斷的小項目,利用的是第三發的虹軟人臉識別的SDK。
下面主要展示頁面功能:照相或照片的方式解析圖片,提取特征;照相或照片的方式對比圖片,判斷相似度;
在引入相關的依賴后和輸入想過的appid和sdk key后,我們主要對調用sdk識別的代碼進行分析
1、JS調用攝像頭拍照,或從本地文件上傳
將照片或者照片文件轉化為64位編碼,向后端傳送
function
getMedia() {$
("#mainDiv").empty();let videoComp
= " <video id='video' width='500px' height='500px' autoplay='autoplay' style='margin-top: 20px'></video><canvas id='canvas' width='500px' height='500px' style='display: none'></canvas>";$
("#mainDiv").append(videoComp
);let constraints
= {video
: {width
: 500, height
: 500},audio
: true};let video
= document
.getElementById("video");let promise
= navigator
.mediaDevices
.getUserMedia(constraints
);promise
.then(function
(MediaStream) {video
.srcObject
= MediaStream;video
.play();});}
function
takePhoto() {let mainComp
= $
("#mainDiv");if(mainComp
.has('video').length
){let userNameInput
= $
("#userName").val();if(userNameInput
== ""){alert("姓名不能為空!");return false;}let video
= document
.getElementById("video");let canvas
= document
.getElementById("canvas");let ctx
= canvas
.getContext('2d');ctx
.drawImage(video
, 0, 0, 500, 500);var formData
= new FormData();var base64File
= canvas
.toDataURL();var userName
= $
("#userName").val();formData
.append("file", base64File
);formData
.append("name", userName
);formData
.append("groupId", "101");$
.ajax({type
: "post",url
: "/faceAdd",data
: formData
,contentType
: false,processData
: false,async
: false,success
: function
(text
) {var res
= JSON
.stringify(text
)if (text
.code
== 0) {alert("注冊成功")} else {alert(text
.message
)}},error
: function
(error
) {alert(JSON
.stringify(error
))}});}else{var formData
= new FormData();let userName
= $
("#userName").val();formData
.append("groupId", "101");var file
= $
("#file0")[0].files
[0];var reader
= new FileReader();reader
.readAsDataURL(file
);reader
.onload
= function
() {var base64
= reader
.result
;formData
.append("file", base64
);formData
.append("name",userName
);$
.ajax({type
: "post",url
: "/faceAdd",data
: formData
,contentType
: false,processData
: false,async
: false,success
: function
(text
) {var res
= JSON
.stringify(text
)if (text
.code
== 0) {alert("注冊成功")} else {alert(text
.message
)}},error
: function
(error
) {alert(JSON
.stringify(error
))}});location
.reload();}}}
2、后端解析圖片,提取人像特征
人像特征的提取主要是靠FaceEngine引擎
人臉添加
@RequestMapping(value
= "/faceAdd", method
= RequestMethod.POST
)@ResponseBodypublic Result<Object> faceAdd(@RequestParam("file") String file
, @RequestParam("groupId") Integer groupId
, @RequestParam("name") String name
) {try {if (file
== null) {return Results.newFailedResult("file is null");}if (groupId
== null) {return Results.newFailedResult("groupId is null");}if (name
== null) {return Results.newFailedResult("name is null");}byte[] decode
= Base64.decode(base64Process(file
));ImageInfo imageInfo
= ImageFactory.getRGBData(decode
);byte[] bytes
= faceEngineService
.extractFaceFeature(imageInfo
);if (bytes
== null) {return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED
);}UserFaceInfo userFaceInfo
= new UserFaceInfo();userFaceInfo
.setName(name
);userFaceInfo
.setGroupId(groupId
);userFaceInfo
.setFaceFeature(bytes
);userFaceInfo
.setFaceId(RandomUtil.randomString(10));userFaceInfoService
.insertSelective(userFaceInfo
);logger
.info("faceAdd:" + name
);return Results.newSuccessResult("");} catch (Exception e
) {logger
.error("", e
);}return Results.newFailedResult(ErrorCodeEnum.UNKNOWN
);}
在人臉添加的控制層,用到了service層邏輯處理,大致看注釋就能明白
@Overridepublic byte[] extractFaceFeature(ImageInfo imageInfo
) throws InterruptedException {FaceEngine faceEngine
= null;try {faceEngine
= faceEngineObjectPool
.borrowObject();List<FaceInfo> faceInfoList
= new ArrayList<FaceInfo>();int i
= faceEngine
.detectFaces(imageInfo
.getImageData(), imageInfo
.getWidth(), imageInfo
.getHeight(), imageInfo
.getImageFormat(), faceInfoList
);if (CollectionUtil.isNotEmpty(faceInfoList
)) {FaceFeature faceFeature
= new FaceFeature();faceEngine
.extractFaceFeature(imageInfo
.getImageData(), imageInfo
.getWidth(), imageInfo
.getHeight(), imageInfo
.getImageFormat(), faceInfoList
.get(0), faceFeature
);return faceFeature
.getFeatureData();}} catch (Exception e
) {logger
.error("", e
);} finally {if (faceEngine
!= null) {faceEngineObjectPool
.returnObject(faceEngine
);}}return null;}
然后將faceFeature存入數據庫即可。
下面是人臉對比分析,性別年齡相似度分析
先看controller層
@RequestMapping(value
= "/faceSearch", method
= RequestMethod.POST
)@ResponseBodypublic Result<FaceSearchResDto> faceSearch(String file
, Integer groupId
) throws Exception {if (groupId
== null) {return Results.newFailedResult("groupId is null");}byte[] decode
= Base64.decode(base64Process(file
));BufferedImage bufImage
= ImageIO.read(new ByteArrayInputStream(decode
));ImageInfo imageInfo
= ImageFactory.bufferedImage2ImageInfo(bufImage
);byte[] bytes
= faceEngineService
.extractFaceFeature(imageInfo
);if (bytes
== null) {return Results.newFailedResult(ErrorCodeEnum.NO_FACE_DETECTED
);}List<FaceUserInfo> userFaceInfoList
= faceEngineService
.compareFaceFeature(bytes
, groupId
);if (CollectionUtil.isNotEmpty(userFaceInfoList
)) {FaceUserInfo faceUserInfo
= userFaceInfoList
.get(0);FaceSearchResDto faceSearchResDto
= new FaceSearchResDto();BeanUtil.copyProperties(faceUserInfo
, faceSearchResDto
);List<ProcessInfo> processInfoList
= faceEngineService
.process(imageInfo
);if (CollectionUtil.isNotEmpty(processInfoList
)) {List<FaceInfo> faceInfoList
= faceEngineService
.detectFaces(imageInfo
);int left
= faceInfoList
.get(0).getRect().getLeft();int top
= faceInfoList
.get(0).getRect().getTop();int width
= faceInfoList
.get(0).getRect().getRight() - left
;int height
= faceInfoList
.get(0).getRect().getBottom() - top
;Graphics2D graphics2D
= bufImage
.createGraphics();graphics2D
.setColor(Color.RED
);BasicStroke stroke
= new BasicStroke(5f);graphics2D
.setStroke(stroke
);graphics2D
.drawRect(left
, top
, width
, height
);ByteArrayOutputStream outputStream
= new ByteArrayOutputStream();System.out
.println("111");System.out
.println(bufImage
.getType());ImageIO.write(bufImage
, "gif", outputStream
);System.out
.println("111");byte[] bytes1
= outputStream
.toByteArray();faceSearchResDto
.setImage("data:image/jpeg;base64," + Base64Utils.encodeToString(bytes1
));faceSearchResDto
.setAge(processInfoList
.get(0).getAge());faceSearchResDto
.setGender(processInfoList
.get(0).getGender().equals(1) ? "女" : "男");}return Results.newSuccessResult(faceSearchResDto
);}return Results.newFailedResult(ErrorCodeEnum.FACE_DOES_NOT_MATCH
);}
再看service層
@Overridepublic List<FaceUserInfo> compareFaceFeature(byte[] faceFeature
, Integer groupId
) throws InterruptedException, ExecutionException {List<FaceUserInfo> resultFaceInfoList
= Lists.newLinkedList();FaceFeature targetFaceFeature
= new FaceFeature();targetFaceFeature
.setFeatureData(faceFeature
);List<FaceUserInfo> faceInfoList
= userFaceInfoMapper
.getUserFaceInfoByGroupId(groupId
); List<List<FaceUserInfo>> faceUserInfoPartList
= Lists.partition(faceInfoList
, 1000);CompletionService<List<FaceUserInfo>> completionService
= new ExecutorCompletionService(executorService
);for (List<FaceUserInfo> part
: faceUserInfoPartList
) {completionService
.submit(new CompareFaceTask(part
, targetFaceFeature
));}for (int i
= 0; i
< faceUserInfoPartList
.size(); i
++) {List<FaceUserInfo> faceUserInfoList
= completionService
.take().get();if (CollectionUtil.isNotEmpty(faceInfoList
)) {resultFaceInfoList
.addAll(faceUserInfoList
);}}resultFaceInfoList
.sort((h1
, h2
) -> h2
.getSimilarValue().compareTo(h1
.getSimilarValue()));return resultFaceInfoList
;}private class CompareFaceTask implements Callable<List<FaceUserInfo>> {private List<FaceUserInfo> faceUserInfoList
;private FaceFeature targetFaceFeature
;public CompareFaceTask(List<FaceUserInfo> faceUserInfoList
, FaceFeature targetFaceFeature
) {this.faceUserInfoList
= faceUserInfoList
;this.targetFaceFeature
= targetFaceFeature
;}@Overridepublic List<FaceUserInfo> call() throws Exception {FaceEngine faceEngine
= null;List<FaceUserInfo> resultFaceInfoList
= Lists.newLinkedList();try {faceEngine
= faceEngineObjectPool
.borrowObject();for (FaceUserInfo faceUserInfo
: faceUserInfoList
) {FaceFeature sourceFaceFeature
= new FaceFeature();sourceFaceFeature
.setFeatureData(faceUserInfo
.getFaceFeature());FaceSimilar faceSimilar
= new FaceSimilar();faceEngine
.compareFaceFeature(targetFaceFeature
, sourceFaceFeature
, faceSimilar
);Integer similarValue
= plusHundred(faceSimilar
.getScore());if (similarValue
> passRate
) {FaceUserInfo info
= new FaceUserInfo();info
.setName(faceUserInfo
.getName());info
.setFaceId(faceUserInfo
.getFaceId());info
.setSimilarValue(similarValue
);resultFaceInfoList
.add(info
);}}} catch (Exception e
) {logger
.error("", e
);} finally {if (faceEngine
!= null) {faceEngineObjectPool
.returnObject(faceEngine
);}}return resultFaceInfoList
;}
大致流程
總結
以上是生活随笔為你收集整理的人脸识别SDK调用与分析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。