• JAVA 进行图片中文字识别(准确度高)!!!


    OCR 识别文字项目

    该项目 可以进行两种方式进行身份证识别

    1. 使用百度接口

    1.1 application-dev.yml配置

    ocr:
      # 使用baiduOcr 需要有Ocr服务器 使用百度需要相应的百度账号即可
      useOcrType: baiduOcr
      # 需要OCR 的文件夹
      ocrFolderPath: E:ocr-wait-image16210910333-8e2fa7f52db04a538ed584c919ce33b1
      # 需要OCR 的文件
      ocrFile: H:Desktop	est14.jpg
      # 百度OCR 配置  https://cloud.baidu.com/doc/OCR/s/Nkibizxlf
      baiduOcr:
        # 使用token 形式
        useToken: false
        # 使用卡证识别接口 卡证识别一天500次免费(识别率高推荐) 通用识别50000次免费(识别率较低)
        useIdCard: true
        # 使用token 形式调用接口 token 通过接口获取(推荐使用sdk模式)
        token: XXXXXXXX
        idCardUrl: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard
        idCardPrefix: id_card_side=front&image=
        generalBasicUrl: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic
        generalBasicPrefix: image=
        # 不使用token sak形式调用接口(通过百度账号创建应用获取)
        appId: XXXXXXXXXX
        apiKey: XXXXXXXXXX
        secretKey: XXXXXXXXXX
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.2 创建百度应用

    1609572779516

    填入必填项即可

    再次出来即有一个创建的应用

    1609572947517

    以上配置的appId,apiKey,secretKey 三项在这里获取

    1.3 结果显示

    1609573117096

    获得结果会保存在这个文件夹

    1609573193329

    1.3 使用百度免费OCR 项目配置结束

    1.4 主要代码展示

    package com.ocr.baidu;
    
    import com.baidu.aip.ocr.AipOcr;
    import com.framework.config.OcrConfig;
    import com.utils.Base64Util;
    import com.utils.FileUtil;
    import com.utils.HttpUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.json.JSONObject;
    
    import java.net.URLEncoder;
    import java.nio.charset.StandardCharsets;
    import java.util.HashMap;
    
    @Slf4j
    public class BaiduOCRUtils {
        /**
         * 卡证识别
         */
        public static String idCardByToken(OcrConfig.BaiduOcr baiduOcr,String filePath) {
            String idCardPrefix = baiduOcr.getIdCardPrefix();
            String idCardUrl = baiduOcr.getIdCardUrl();
            String token = baiduOcr.getToken();
            // 请求url
            try {
                // 本地文件路径
    
                byte[] imgData = FileUtil.readFileByBytes(filePath);
                String imgStr = Base64Util.encode(imgData);
                String imgParam = URLEncoder.encode(imgStr, StandardCharsets.UTF_8.name());
    
                String param = idCardPrefix + imgParam;
                // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                return  HttpUtil.post(idCardUrl, token, param);
            } catch (Exception e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 通用文字识别
         */
        public static String generalBasicByToken(OcrConfig.BaiduOcr baiduOcr,String filePath) {
            String generalBasicPrefix = baiduOcr.getGeneralBasicPrefix();
            String generalBasicUrl = baiduOcr.getGeneralBasicUrl();
            String token = baiduOcr.getToken();
            // 请求url
            try {
                // 本地文件路径
                byte[] imgData = FileUtil.readFileByBytes(filePath);
                String imgStr = Base64Util.encode(imgData);
                String imgParam = URLEncoder.encode(imgStr, StandardCharsets.UTF_8.name());
    
                String param = generalBasicPrefix + imgParam;
                // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                return HttpUtil.post(generalBasicUrl, token, param);
            } catch (Exception e) {
                log.error(e.getMessage());
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 通用文字识别 sdk
         */
        public static JSONObject generalBasicBySdk(OcrConfig.BaiduOcr baiduOcr,String filePath) {
            String appId = baiduOcr.getAppId();
            String apiKey = baiduOcr.getApiKey();
            String secredKey = baiduOcr.getSecretKey();
            AipOcr client = new AipOcr(appId, apiKey, secredKey);
            // 可选:设置网络连接参数
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);
            return client.basicGeneral(filePath, new HashMap<>());
        }
        /**
         * 身份证文字识别 sdk
         */
        public static JSONObject idCardBySdk(OcrConfig.BaiduOcr baiduOcr,String filePath) {
            String appId = baiduOcr.getAppId();
            String apiKey = baiduOcr.getApiKey();
            String secredKey = baiduOcr.getSecretKey();
            AipOcr client = new AipOcr(appId, apiKey, secredKey);
            // 可选:设置网络连接参数
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);
            return client.idcard(filePath,"front", new HashMap<>());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    2. 使用百度开源项目PaddleHub

    PS: 识别通过paddle(python 运行) ,JAVA 进行结果处理

    2.1 按照教程安装PaddleHub

    2.2 application-dev.yml配置

    ocr:
      paddleOcr:
        # 使用本地
        url: 192.168.0.106
        port: 8866
        moduleMap:
          # 文字识别OCR 安装 https://www.paddlepaddle.org.cn/hubdetail?name=chinese_ocr_db_crnn_mobile&en_category=TextRecognition
          chinese_ocr_db_crnn_mobile: 1.1.1
          # 人脸识别OCR(识别身份证正面或手持身份证) 安装  https://www.paddlepaddle.org.cn/hubdetail?name=pyramidbox_lite_server&en_category=FaceDetection
          pyramidbox_lite_server: 1.2.0
        # 是否分析
        analysis: false
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.3 结果显示

    1609573117096

    获得结果会保存在这个文件夹

    1609573904556

    2.4 主要代码展示

    package com.ocr.paddle;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.google.common.collect.Lists;
    import com.ocr.paddle.domain.LocalHubOcrResultDTO;
    import com.ocr.paddle.domain.OCRHubResultDTO;
    import com.utils.Base64Util;
    import com.utils.FileUtil;
    import com.utils.HttpClientUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    @Slf4j
    public class LocalHubOcrUtils {
    
        public static List<LocalHubOcrResultDTO> localAllOcr(String textUrl, String faceUrl, List<File> allFiles) {
            long l = System.currentTimeMillis();
            List<LocalHubOcrResultDTO> localOcrResultDTOList = Lists.newArrayList();
            int urlCount = 0;
            boolean useTextUrl = false;
            boolean useFaceUrl = false;
            if (StringUtils.isEmpty(textUrl)) {
                log.info("不进行文字识别");
            } else {
                urlCount++;
                useTextUrl = true;
                log.info("需要进行文字识别");
            }
            if (StringUtils.isEmpty(faceUrl)) {
                log.info("不进行人脸识别");
            } else {
                urlCount++;
                useFaceUrl = true;
                log.info("需要进行人脸识别");
            }
            int ocrCount = allFiles.size() * urlCount;
            log.info("预估进行OCR" + ocrCount + "次");
            if (ocrCount == 0) {
                return localOcrResultDTOList;
            }
    
            int textIndex = 0;
            int faceIndex = 0;
            // 本地文件路径
            Map<String, String> partentFile = allFiles.stream().collect(Collectors.toMap(File::getName, File::getParent, (e1, e2) -> e1));
            for (File imageFile : allFiles) {
                List<OCRHubResultDTO> ocrHubResultDTOS = Lists.newArrayList();
    
                byte[] imgData = new byte[0];
                try {
                    imgData = FileUtil.readFileByBytes(imageFile);
                } catch (IOException e) {
                    log.error("图片读取错误");
                    continue;
                }
                String imgStr = Base64Util.encode(imgData);
                JSONObject jsonObject = new JSONObject();
                List<String> imageParams = Lists.newArrayList();
                imageParams.add(imgStr);
                jsonObject.put("images", imageParams);
    
                String textResult = "";
                if (useTextUrl) {
                    textResult = HttpClientUtils.sendJsonStr(textUrl, jsonObject.toJSONString());
                    textIndex++;
                    log.info("已进行文字OCR" + textIndex + "次");
                    if (StringUtils.isEmpty(textResult)) {
                        log.error("获取文字接口失败");
                        log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
                        continue;
                    }
                    JSONObject resultTest = (JSONObject) JSONObject.parse(textResult);
                    JSONArray textResultsArray = resultTest.getJSONArray("results");
                    if (textResultsArray == null){
                        log.error("返回值错误,错误信息为:" + textResult);
                    }
    
                    for (Object o : textResultsArray) {
                        JSONObject j = (JSONObject) o;
                        JSONArray data = j.getJSONArray("data");
                        for (Object datum : data) {
                            JSONObject jo = (JSONObject) datum;
                            jo.remove("text_box_position");
                            OCRHubResultDTO ocrHubResultDTO = jo.toJavaObject(OCRHubResultDTO.class);
                            ocrHubResultDTOS.add(ocrHubResultDTO);
                        }
                    }
    
                }
                int faceCount = 0;
                String faceResult = "";
                if (useFaceUrl) {
                    faceResult = HttpClientUtils.sendJsonStr(faceUrl, jsonObject.toJSONString());
                    faceIndex++;
                    log.info("已进行人脸OCR" + faceIndex + "次");
                    if (StringUtils.isEmpty(faceResult)) {
                        log.error("获取人脸识别接口失败");
                        log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
                        continue;
                    }
                    JSONObject resultFace = (JSONObject) JSONObject.parse(faceResult);
                    JSONArray faceResultsArray = resultFace.getJSONArray("results");
                    for (Object o : faceResultsArray) {
                        JSONObject j = (JSONObject) o;
                        JSONArray data = j.getJSONArray("data");
                        faceCount = data.size();
                    }
                }
    
                log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
                localOcrResultDTOList.add(new LocalHubOcrResultDTO(imageFile.getAbsolutePath(), imageFile.getParent(), ocrHubResultDTOS, faceCount));
            }
            log.info("OCR 总耗时" + (System.currentTimeMillis() - l) / 1000 + "S");
            log.info("OCR 次数" + ocrCount + "次");
            log.info("OCR 平均耗时" + (System.currentTimeMillis() - l) / 1000 / ocrCount + "s");
            return localOcrResultDTOList;
        }
    
        private static void func(File file, List<File> fileList) {
            File[] fs = file.listFiles();
            for (File f : fs) {
                if (f.isDirectory()) {
                    //若是目录,则递归打印该目录下的文件
                    func(f, fileList);
                }
                if (f.isFile()) {
                    String imageName = f.getName();
                    boolean isJpg = imageName.endsWith(".jpg");
                    boolean isJPG = imageName.endsWith(".JPG");
                    boolean isPng = imageName.endsWith(".png");
                    if (isJPG || isPng || isJpg) {
                        //若是图片加入列表
                        fileList.add(f);
                    }
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146

    sJpg = imageName.endsWith(".jpg");
    boolean isJPG = imageName.endsWith(".JPG");
    boolean isPng = imageName.endsWith(".png");
    if (isJPG || isPng || isJpg) {
    //若是图片加入列表
    fileList.add(f);
    }
    }
    }
    }
    }

    原文章:https://blog.csdn.net/AirOrange_qi/article/details/112102739

  • 相关阅读:
    Spring+Springmvc+SpringJDBC+freemaker+Logback配置
    POJ1942+找规律
    HDU2955+DP+背包变形
    HDU1201+简单题
    HDU1288+枚举
    面试经验(转)
    HDU1864+dp+类似背包
    PKU1659+havelhakimi定理
    算法复杂度分析(摘)
    HDU3047+并查集
  • 原文地址:https://www.cnblogs.com/tfil/p/14228354.html
Copyright © 2020-2023  润新知