欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-04 11:32:30
OCR 识别文字项目该项目 可以进行两种方式进行身份证识别1. 使用百度接口1.1 application-dev.yml配置ocr: # 使用baiduOcr 需要有Ocr服务器 使用百度需要相应的百度账号即可 useOcrType: baiduOcr # 需要OCR 的文件夹 ocrFolderPath: E:\ocr-wait-image\16210910333-8e2fa7f52db04a538ed584c919ce33b1 # 需要OCR 的文件 ocrFile:...

OCR 识别文字项目

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

1. 使用百度接口

1.1 application-dev.yml配置

ocr:
  # 使用baiduOcr 需要有Ocr服务器 使用百度需要相应的百度账号即可
  useOcrType: baiduOcr
  # 需要OCR 的文件夹
  ocrFolderPath: E:\ocr-wait-image\16210910333-8e2fa7f52db04a538ed584c919ce33b1
  # 需要OCR 的文件
  ocrFile: H:\Desktop\test\14.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 创建百度应用

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

填入必填项即可

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

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

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

1.3 结果显示

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

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

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

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<>());
    }
}

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

2.3 结果显示

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

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

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

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);
                }
            }
        }
    }
}

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