shikeying
2024-01-30 1a56cbb4cc61382d67be150acb2c3a91a679a808
添加百度ai相关实现
8个文件已添加
6个文件已修改
495 ■■■■■ 已修改文件
walker-jdbc-support/walker-jdbc-support-oracle/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-pay-support-payunk/src/test/java/com/walker/pay/payunk/TestPayUnkEngine.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-scheduler/src/test/java/com/walker/scheduler/TestScheduler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-web-security/src/main/java/com/walker/web/security/DefaultAccessDeniedHandler.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-web/src/main/java/com/walker/web/ResponseCode.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
walker-ml-openocr/src/main/java/com/walker/openocr/AbstractFaceRecognize.java
New file
@@ -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());
}
walker-ml-openocr/src/main/java/com/walker/openocr/FaceDetectResult.java
New file
@@ -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】,代表这是一张人脸的概率,0最小、1最大
    private int age = 0;
    private boolean smile = false;
    private String gender = null;       // 性别,male:男性 female:女性
    private boolean glasses = false;    // 是否带眼镜,face_field包含glasses时返回
    private String faceType = null;     // 人脸类型,human: 真实人脸 cartoon: 卡通人脸
    private double faceTypeProbability = 0; // 人脸类型判断正确的置信度,范围【0~1】,0代表概率最小、1代表最大
}
walker-ml-openocr/src/main/java/com/walker/openocr/FaceMatchResult.java
New file
@@ -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 + '\'' +
                '}';
    }
}
walker-ml-openocr/src/main/java/com/walker/openocr/FaceRecognize.java
New file
@@ -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:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;
     * 2) URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
     * 3) FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。
     * </pre>
     * @param image 图像内容,根据type定。
     * @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 活体检测选项:LOW/NORMAL/HIGH
     * @return
     */
    double matchTwoImageBase64(String photo_live_base64, String imageBase64, String livenessControl);
}
walker-ml-openocr/src/main/java/com/walker/openocr/support/BaiduFaceRecognize.java
New file
@@ -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){
        // 活体检测选项:LOW/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){
        // 活体检测选项:LOW/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;
}
walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceItem.java
New file
@@ -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;
    }
}
walker-ml-openocr/src/main/java/com/walker/openocr/util/FaceUtils.java
New file
@@ -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;
        }
    }
}
walker-ml-openocr/src/test/java/com/walker/openocr/BaiduFaceTest.java
New file
@@ -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);
    }
}
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);
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();
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());
        }
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"),
walker-web/src/main/java/com/walker/web/annotation/RepeatSubmit.java
@@ -9,7 +9,7 @@
/**
 * 自定义注解防止表单重复提交
 *
 *
 * @author 时克英
 * @date 2022-10-10
 */
@@ -22,7 +22,7 @@
    /**
     * 间隔时间(ms),小于此时间视为重复提交
     */
    public int interval() default 5000;
    public int interval() default 2000;
    /**
     * 提示消息