From 1a56cbb4cc61382d67be150acb2c3a91a679a808 Mon Sep 17 00:00:00 2001 From: shikeying <pxzsky@163.com> Date: 星期二, 30 一月 2024 17:34:49 +0800 Subject: [PATCH] 添加百度ai相关实现 --- walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java | 123 +++++++++++++ walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java | 28 +++ walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java | 2 walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java | 2 walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java | 4 walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java | 53 +++++ walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java | 150 ++++++++++++++++ walker-web/src/main/java/com/walker/web/ResponseCode.java | 2 walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java | 29 +++ walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java | 4 walker-jdbc-support/walker-jdbc-support-oracle/pom.xml | 2 walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java | 9 + walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java | 34 +++ walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java | 53 +++++ 14 files changed, 487 insertions(+), 8 deletions(-) diff --git a/walker-jdbc-support/walker-jdbc-support-oracle/pom.xml b/walker-jdbc-support/walker-jdbc-support-oracle/pom.xml index 848e95c..412cdfe 100644 --- a/walker-jdbc-support/walker-jdbc-support-oracle/pom.xml +++ b/walker-jdbc-support/walker-jdbc-support-oracle/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>walker-jdbc-support</artifactId> <groupId>com.walkersoft</groupId> - <version>2.3.0-SNAPSHOT</version> + <version>2.7.18</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java b/walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java new file mode 100644 index 0000000..c00df64 --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java @@ -0,0 +1,9 @@ +package com.walker.openocr; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractFaceRecognize implements FaceRecognize { + + protected final transient Logger logger = LoggerFactory.getLogger(this.getClass()); +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java new file mode 100644 index 0000000..d0fa872 --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java @@ -0,0 +1,123 @@ +package com.walker.openocr; + +public class FaceDetectResult { + + public int getFaceNum() { + return faceNum; + } + + public void setFaceNum(int faceNum) { + this.faceNum = faceNum; + } + + public String getFaceToken() { + return faceToken; + } + + public void setFaceToken(String faceToken) { + this.faceToken = faceToken; + } + + public double getLeft() { + return left; + } + + public void setLeft(double left) { + this.left = left; + } + + public double getTop() { + return top; + } + + public void setTop(double top) { + this.top = top; + } + + public double getWidth() { + return width; + } + + public void setWidth(double width) { + this.width = width; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getFaceProbability() { + return faceProbability; + } + + public void setFaceProbability(double faceProbability) { + this.faceProbability = faceProbability; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public boolean isSmile() { + return smile; + } + + public void setSmile(boolean smile) { + this.smile = smile; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public boolean isGlasses() { + return glasses; + } + + public void setGlasses(boolean glasses) { + this.glasses = glasses; + } + + public String getFaceType() { + return faceType; + } + + public void setFaceType(String faceType) { + this.faceType = faceType; + } + + public double getFaceTypeProbability() { + return faceTypeProbability; + } + + public void setFaceTypeProbability(double faceTypeProbability) { + this.faceTypeProbability = faceTypeProbability; + } + + private int faceNum = 1; + private String faceToken; + private double left = 0; + private double top = 0; + private double width = 0; + private double height = 0; + private double faceProbability = 0; // 浜鸿劯缃俊搴︼紝鑼冨洿銆�0~1銆戯紝浠h〃杩欐槸涓�寮犱汉鑴哥殑姒傜巼锛�0鏈�灏忋��1鏈�澶� + private int age = 0; + private boolean smile = false; + private String gender = null; // 鎬у埆锛宮ale:鐢锋�� female:濂虫�� + private boolean glasses = false; // 鏄惁甯︾溂闀滐紝face_field鍖呭惈glasses鏃惰繑鍥� + private String faceType = null; // 浜鸿劯绫诲瀷锛宧uman: 鐪熷疄浜鸿劯 cartoon: 鍗¢�氫汉鑴� + private double faceTypeProbability = 0; // 浜鸿劯绫诲瀷鍒ゆ柇姝g‘鐨勭疆淇″害锛岃寖鍥淬��0~1銆戯紝0浠h〃姒傜巼鏈�灏忋��1浠h〃鏈�澶� + +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java new file mode 100644 index 0000000..c9897fd --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java @@ -0,0 +1,53 @@ +package com.walker.openocr; + +public class FaceMatchResult { + + /** + * 瀵规瘮浜鸿劯缁撴灉璇勫垎锛屾帹鑽愰槇鍊�80鍒� + * @return + */ + public double getScore() { + return score; + } + + public void setScore(double score) { + this.score = score; + } + + /** + * 鑾峰緱鍘熷浜鸿劯鍥惧儚token + * @return + */ + public String getSrcToken() { + return srcToken; + } + + public void setSrcToken(String srcToken) { + this.srcToken = srcToken; + } + + /** + * 鑾峰緱鐩爣浜鸿劯鍥惧儚token + * @return + */ + public String getDestToken() { + return destToken; + } + + public void setDestToken(String destToken) { + this.destToken = destToken; + } + + private double score = 0; + private String srcToken; + private String destToken; + + @Override + public String toString() { + return "FaceMatchResult{" + + "score=" + score + + ", srcToken='" + srcToken + '\'' + + ", destToken='" + destToken + '\'' + + '}'; + } +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java new file mode 100644 index 0000000..0252b55 --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java @@ -0,0 +1,53 @@ +package com.walker.openocr; + +import com.walker.openocr.util.FaceItem; + +/** + * 浜鸿劯璇嗗埆瑙勮寖瀹氫箟銆� + * @author 鏃跺厠鑻� + * @date 2024-01-30 + */ +public interface FaceRecognize { + + /** + * 浜鸿劯妫�娴� + * <pre> + * 鍥剧墖绫诲瀷 + * 1) BASE64:鍥剧墖鐨刡ase64鍊硷紝base64缂栫爜鍚庣殑鍥剧墖鏁版嵁锛岀紪鐮佸悗鐨勫浘鐗囧ぇ灏忎笉瓒呰繃2M锛� + * 2) URL:鍥剧墖鐨� URL鍦板潃( 鍙兘鐢变簬缃戠粶绛夊師鍥犲鑷翠笅杞藉浘鐗囨椂闂磋繃闀�)锛� + * 3) FACE_TOKEN: 浜鸿劯鍥剧墖鐨勫敮涓�鏍囪瘑锛岃皟鐢ㄤ汉鑴告娴嬫帴鍙f椂锛屼細涓烘瘡涓汉鑴稿浘鐗囪祴浜堜竴涓敮涓�鐨凢ACE_TOKEN锛屽悓涓�寮犲浘鐗囧娆℃娴嬪緱鍒扮殑FACE_TOKEN鏄悓涓�涓�� + * </pre> + * @param image 鍥惧儚鍐呭锛屾牴鎹畉ype瀹氥�� + * @param imageType 鍥惧儚绫诲瀷 + * @param option + * @return + */ + FaceDetectResult detect(String image, String imageType, Object option); + +// /** +// * 涓や釜浜鸿劯瀵规瘮銆� +// * @return +// */ +// FaceMatchResult match(); + + double matchTwoFace(FaceItem face1, FaceItem face2); + + double matchTwoImageFile(String file1, String file2); + + /** + * 瀵规瘮涓ゅ紶鐓х墖锛屽垽鏂槸鍚﹀悓涓�浜� + * @param photo_live_base64 + * @param imageBase64 + * @return + */ + double matchTwoImageBase64(String photo_live_base64, String imageBase64); + + /** + * 瀵规瘮涓ゅ紶鐓х墖锛屽垽鏂槸鍚﹀悓涓�浜猴紝澧炲姞浜嗕竴涓緭鍏ュ弬鏁帮紙娲讳綋绾у埆锛� + * @param photo_live_base64 + * @param imageBase64 + * @param livenessControl 娲讳綋妫�娴嬮�夐」锛歀OW/NORMAL/HIGH + * @return + */ + double matchTwoImageBase64(String photo_live_base64, String imageBase64, String livenessControl); +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java b/walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java new file mode 100644 index 0000000..bf4c04a --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java @@ -0,0 +1,150 @@ +package com.walker.openocr.support; + +import com.baidu.aip.face.AipFace; +import com.baidu.aip.face.MatchRequest; +import com.walker.infrastructure.utils.StringUtils; +import com.walker.openocr.AbstractFaceRecognize; +import com.walker.openocr.FaceDetectResult; +import com.walker.openocr.util.FaceItem; +import com.walker.openocr.util.FaceUtils; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class BaiduFaceRecognize extends AbstractFaceRecognize { + +// private HashMap<String, String> options; + + @Override + public FaceDetectResult detect(String image, String imageType, Object option) { + throw new UnsupportedOperationException("鏈疄鐜颁汉鑴告娴嬫帴鍙�"); + } + + @Override + public double matchTwoFace(FaceItem face1, FaceItem face2){ + logger.debug(face1.getFaceToken() + ", " + face2.getFaceToken()); + MatchRequest req1 = new MatchRequest(face1.getFaceToken(), "FACE_TOKEN"); + MatchRequest req2 = new MatchRequest(face2.getFaceToken(), "FACE_TOKEN"); + ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>(); + requests.add(req1); + requests.add(req2); + + JSONObject res = client.match(requests); + logger.info("matchTwoFace(FaceItem) result = {}", res); + return 0; + } + + @Override + public double matchTwoImageFile(String file1, String file2){ + MatchRequest req1 = new MatchRequest(FaceUtils.getImageBase64(file1), "BASE64"); + MatchRequest req2 = new MatchRequest(FaceUtils.getImageBase64(file2), "BASE64"); + List<MatchRequest> requests = new ArrayList<MatchRequest>(); + requests.add(req1); + requests.add(req2); + + try{ + return this.doMatchProcess(requests); + } catch(RuntimeException ex){ + throw ex; + } + } + + @Override + public double matchTwoImageBase64(String photo_live_base64, String imageBase64){ + // 娲讳綋妫�娴嬮�夐」锛歀OW/NORMAL/HIGH + MatchRequest req1 = new MatchRequest(photo_live_base64, "BASE64","LIVE", "NORMAL","LOW"); + MatchRequest req2 = new MatchRequest(imageBase64, "BASE64", "CERT", null, null); + ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>(); + requests.add(req1); + requests.add(req2); + + try{ + return this.doMatchProcess(requests); + } catch(RuntimeException ex){ + throw ex; + } + } + + @Override + public double matchTwoImageBase64(String photo_live_base64, String imageBase64, String livenessControl){ + // 娲讳綋妫�娴嬮�夐」锛歀OW/NORMAL/HIGH + MatchRequest req1 = new MatchRequest(photo_live_base64, "BASE64","LIVE", "NORMAL",livenessControl); + MatchRequest req2 = new MatchRequest(imageBase64, "BASE64", "CERT", null, null); + ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>(); + requests.add(req1); + requests.add(req2); + + try{ + return this.doMatchProcess(requests); + } catch(RuntimeException ex){ + throw ex; + } + } + + private double doMatchProcess(List<MatchRequest> requests){ + JSONObject res = client.match(requests); + if(res == null){ +// logger.error("璋冪敤matchTwoImage鎺ュ彛锛岃繑鍥炵┖鏁版嵁"); + throw new RuntimeException("璋冪敤matchTwoImage鎺ュ彛锛岃繑鍥炵┖鏁版嵁"); + } + logger.info("face match result = {}", res); + + if(res.getInt("error_code") != 0){ + logger.error("璋冪敤detect鎺ュ彛锛岃繑鍥為敊璇暟鎹細" + res.getString("error_msg")); + throw new RuntimeException(res.getString("error_msg")); + } + + JSONObject result = res.getJSONObject("result"); + return result.getDouble("score"); + } + + public void checkFaceClient(){ + if(this.client == null){ + if(StringUtils.isEmpty(this.appId) || StringUtils.isEmpty(this.apiKey) || StringUtils.isEmpty(this.secretKey)){ + throw new IllegalArgumentException("appId, apiKey, secretKey涓虹┖锛屾棤娉曞垵濮嬪寲鐧惧害OCR client!"); + } + client = new AipFace(this.appId, this.apiKey, this.secretKey); + // 鍙�夛細璁剧疆缃戠粶杩炴帴鍙傛暟 + client.setConnectionTimeoutInMillis(2000); + client.setSocketTimeoutInMillis(60000); + + // 浼犲叆鍙�夊弬鏁拌皟鐢ㄦ帴鍙� +// options = new HashMap<String, String>(); +// options.put("language_type", "CHN_ENG"); +// options.put("detect_direction", "true"); +// options.put("detect_language", "true"); +// options.put("probability", "true"); + logger.info("鐧惧害: AipFace鍒濆鍖栨垚鍔�"); + } + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + private String appId; + private String apiKey; + private String secretKey; + private AipFace client; +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java b/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java new file mode 100644 index 0000000..35cf79a --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java @@ -0,0 +1,34 @@ +package com.walker.openocr.util; + +/** + * 鎻忚堪锛� + * @author 鏃跺厠鑻� + * @date 2020骞�2鏈�18鏃� 涓嬪崍9:10:09 + */ + +public class FaceItem { + + private String faceToken; + private double liveScore = 0.0; + private String summary; + + public String getFaceToken() { + return faceToken; + } + public void setFaceToken(String faceToken) { + this.faceToken = faceToken; + } + public double getLiveScore() { + return liveScore; + } + public void setLiveScore(double liveScore) { + this.liveScore = liveScore; + } + public String getSummary() { + return summary; + } + public void setSummary(String summary) { + this.summary = summary; + } + +} diff --git a/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java b/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java new file mode 100644 index 0000000..d2dea7c --- /dev/null +++ b/walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java @@ -0,0 +1,28 @@ +package com.walker.openocr.util; + +import org.apache.commons.codec.binary.Base64; +import org.springframework.util.FileCopyUtils; + +import java.io.File; +import java.io.IOException; + +/** + * 鎻忚堪锛� + * @author 鏃跺厠鑻� + * @date 2020骞�2鏈�18鏃� 涓嬪崍10:06:57 + */ + +public class FaceUtils { + + public static final String getImageBase64(String filePath){ + byte[] fileBytes; + try { + fileBytes = FileCopyUtils.copyToByteArray(new File(filePath)); + byte[] fileBase64 = Base64.encodeBase64(fileBytes); + return new String(fileBase64); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java b/walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java new file mode 100644 index 0000000..892d028 --- /dev/null +++ b/walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java @@ -0,0 +1,29 @@ +package com.walker.openocr; + +import com.baidu.aip.face.AipFace; +import com.walker.openocr.support.BaiduFaceRecognize; +import org.junit.Test; + +public class BaiduFaceTest { + + public static final String APP_ID = "18547554"; + public static final String API_KEY = "epNhm4LRAhSpDTCB6Wfc8VQO"; + public static final String SECRET_KEY = "ICwmmmVQB7A89dhtiPfu0q8OiwDh1Qpb"; + + private AipFace client = null; + private BaiduFaceRecognize faceRecognize = null; + + @Test + public void faceMatch(){ + this.faceRecognize = new BaiduFaceRecognize(); + this.faceRecognize.setAppId(APP_ID); + this.faceRecognize.setApiKey(API_KEY); + this.faceRecognize.setSecretKey(SECRET_KEY); + this.faceRecognize.checkFaceClient(); + + // 浜鸿劯瀵规瘮锛堜袱寮犲浘鐗囷級 +// double score = faceRecognize.matchTwoImageFile("F:/鍥剧墖/sfz01.jpg", "F:/鍥剧墖/shl01.jpg"); + double score = faceRecognize.matchTwoImageFile("F:/鍥剧墖/mike.jpg", "F:/鍥剧墖/mike_card.jpg"); + System.out.println("score = " + score); + } +} diff --git a/walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java b/walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java index 9dae513..804dd28 100644 --- a/walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java +++ b/walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java @@ -30,7 +30,7 @@ System.out.println(MoneyUtils.scaleYuan2Accuracy(1)); } - @Test +// @Test public void payAliAnDf(){ RestTemplate restTemplate = this.getRestTemplate(); PayEngineProvider payEngineProvider = new PayUnkEngineProvider(restTemplate); diff --git a/walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java b/walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java index 72c91fb..9e4b881 100644 --- a/walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java +++ b/walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java @@ -7,7 +7,7 @@ public class TestScheduler { - @Test +// @Test public void testEveryDayOnce(){ EveryDayScheduler scheduler = new EveryDayScheduler(1, "鏈烘瀯淇℃伅鍚屾"); Option option = new Option(); diff --git a/walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java b/walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java index 63ea783..ddec7e3 100644 --- a/walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java +++ b/walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java @@ -1,7 +1,6 @@ package com.walker.web.security; import com.walker.infrastructure.utils.JsonUtils; -import com.walker.web.ResponseCode; import com.walker.web.ResponseValue; import com.walker.web.util.ServletUtils; import org.slf4j.Logger; @@ -27,7 +26,8 @@ public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { String msg = "宸茶璇�,浣嗘湭鍒嗛厤绯荤粺鏉冮檺:" + request.getRequestURI(); try { - ServletUtils.renderString(response, JsonUtils.objectToJsonString(ResponseValue.error(ResponseCode.NO_PERMISSION.getCode(), msg))); +// ServletUtils.renderString(response, JsonUtils.objectToJsonString(ResponseValue.error(ResponseCode.NO_PERMISSION.getCode(), msg))); + ServletUtils.renderString(response, JsonUtils.objectToJsonString(ResponseValue.error(msg))); } catch (Exception e) { logger.error("鏈垎閰嶇郴缁熸潈闄�:" + request.getRequestURI()); } diff --git a/walker-web/src/main/java/com/walker/web/ResponseCode.java b/walker-web/src/main/java/com/walker/web/ResponseCode.java index a586539..1a6c406 100644 --- a/walker-web/src/main/java/com/walker/web/ResponseCode.java +++ b/walker-web/src/main/java/com/walker/web/ResponseCode.java @@ -11,7 +11,7 @@ * 瀵瑰悗鍙版櫘閫氬紓甯革紝鍓嶇浠呰繑鍥炰竴涓彁绀猴紝鑰屼笖涓嶄細寮瑰嚭鍒扮晫闈紝涓昏鐢ㄤ簬鎺ュ彛鍙嶉銆� * @date 2024-01-05 */ - EXCEPTION(-1, "绯荤粺閿欒"), + EXCEPTION(-9, "绯荤粺閿欒"), /* 鎴愬姛 */ SUCCESS(1, "success"), diff --git a/walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java b/walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java index 9c8d141..11d2f9b 100644 --- a/walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java +++ b/walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java @@ -9,7 +9,7 @@ /** * 鑷畾涔夋敞瑙i槻姝㈣〃鍗曢噸澶嶆彁浜� - * + * * @author 鏃跺厠鑻� * @date 2022-10-10 */ @@ -22,7 +22,7 @@ /** * 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦 */ - public int interval() default 5000; + public int interval() default 2000; /** * 鎻愮ず娑堟伅 -- Gitblit v1.9.1