【信息提取】⭐️Springboot 实现图片的文字检测和信息提取

目录

🍸前言

🍻一、工具选择

🍹二、代码实现

        2.1 依赖引入

         2.2 方法实现

💞️三、测试

 🍻四、章末


🍸前言

        小伙伴们大家好,最近在公众号上刷到如何在 java 中实现图片的识别和信息提取,巧了,鄙人毕设是有关人脸识别的,其中有一步骤就是图片的处理加信息提取,只不过是在 python 中使用的;闲暇无事,本地测试下在 Java 中要怎么实现从证件图片中提取身份信息

        Ps:毕设中用的 python 实现可以参考下这篇文章(想想自己的论文,有点水了(bushi):

《Python人脸识别实现指南》_python人脸识别训练代码-CSDN博客

🍻一、工具选择

        图片处理通常会使用光学字符识别(OCR)技术,查了下,比较常用的 OCR 工具有 Tesseract,可以帮助从指定图片中提取文本信息。

        该工具的使用也比较简单,首先要安装 Tesseract OCR,然后引入相关的库即可;下载地址如下,选择好版本之后,可以自行下载,本地选择的是下载 exe 文件,本地安装一路 next 就行。但是要记住安装位置,因为代码中要引用安装包中的部分文件

Release 5.5.0 · tesseract-ocr/tesseract · GitHub

 

🍹二、代码实现

        2.1 依赖引入

        可以使用 Tess4J 这个 Java 的 Tesseract 包装库来集成 Tesseract OCR。

        <dependency>
            <groupId>net.sourceforge.tess4j</groupId>
            <artifactId>tess4j</artifactId>
            <version>4.5.0</version> <!-- 自行选择版本 -->
        </dependency>
         2.2 方法实现

        这里可以直接写成工具类,但是为了方便拓展,可以结合策略模式,具体就是,针对不同的证件图片,都有对应的处理方式,如果有新增的类型,可以不用过多改动原有代码,而是不断扩展(开闭原则);整体的思路就是通过策略工厂和不同的策略类实现;

        2.2.1 考虑到图片类型的增加,为了方便用枚举类来进行管理,目前就放了一种卡类型,后面要增加的话依次填写枚举值即可

public enum CardTypeEnum {
    IDCARD;
}

        2.2.2 创建一个具体的识别结果类,用来统一管理每种策略的处理结果

@Data
public class OcrResp {

    //姓名
    private String name;

    //证件号码
    private String idNum;

    //出生日期
    private String birth;

    //有效时间
    private String usefulPeriod;

    //到期时间
    private String validPeriod;


}

        2.2.3 用抽象方法来定义图片识别提取的策略,这里另外提供了一个获取卡类型枚举的方法,主要是为了区分每个策略类针对的卡类型,每个策略类都要重写该方法,并返回自己对应的卡类型枚举值。

public abstract class AbstractOcrStrategy {

    public abstract CardTypeEnum getCardEnum();

    public abstract OcrResp ocr(String imagePath);
}

        2.2.4 策略实现类,目前就只有一中卡类型,对应一个策略类;

        整体比较简单,继承策略类之后,重写获取枚举值方法,和ocr方法的具体实现;这里要注意 tessDataPath 常量的取值,是一个文件的路径,对应的就是我们下载的tess ocr 安装的地址,需要使用其中的文件;

        还有一个就是 result 是我们识别图片得到的文本信息,后端面的操作是使用正则去提取每一个我们想要的文本信息。

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author HuangBenben 
 */
@Component
public class IdCardStrategy extends AbstractOcrStrategy{

    @Override
    public CardTypeEnum getCardEnum() {
        return CardTypeEnum.IDCARD;
    }

    private final String tessDataPath = "C:/SoftWares/ocr_tool/tessdata"; // Tesseract 数据路径(如 tessdata)

    @Override
    public OcrResp ocr(String imagePath) {
        OcrResp ocrResp = new OcrResp();
        try {
            File imageFile = new File(imagePath);
            ITesseract instance = new Tesseract();

            // 设置 Tesseract 数据路径
            instance.setDatapath(tessDataPath);
            instance.setLanguage("eng"); // 设置语言

            // 读取图像并进行 OCR 识别
            String result = instance.doOCR(imageFile);

            // 假设身份证号为18位数字:xxxxxx xxxxxxx xxxxx
            Pattern idPattern = Pattern.compile("\\d{17}[\\dXx]"); // 匹配身份证号
            Matcher idMatcher = idPattern.matcher(result);

            if (idMatcher.find()) {
                String idNumber = idMatcher.group();
                ocrResp.setIdNum(idNumber);
            }

            // 1. 提取 Name
            Pattern namePattern = Pattern.compile("Name\\s*(.*)");
            Matcher nameMatcher = namePattern.matcher(result);
            if (nameMatcher.find()) {
                ocrResp.setName(nameMatcher.group(1));
            }

            // 2. 提取出生日期
            Pattern datePattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2})");
            Matcher dateMatcher = datePattern.matcher(result);
            if (dateMatcher.find()) {
                ocrResp.setBirth(dateMatcher.group(1));
            }

            // 4. 提取签发日期和到期日期
            Pattern validityPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2})\\s*-\\s*(\\d{4}\\.\\d{2}\\.\\d{2})");
            Matcher validityMatcher = validityPattern.matcher(result);
            if (validityMatcher.find()) {
                ocrResp.setUsefulPeriod(validityMatcher.group(1));
                ocrResp.setValidPeriod(validityMatcher.group(2));
            }
            return ocrResp;
        } catch (Exception e) {
            System.err.println("OCR识别失败: " + e.getMessage());
        }
        return null;
    }
}

        2.2.5 策略工厂

        @Component 注解标注是由 Spring 管理的组件

        使用静态容器在 bean 初始化之后存储每种策略实现类;先扫描出策略类的所有实现,然后根据每个实现类返回的枚举值进行存储,key 对应的就是卡类型枚举, value 就是对应的策略类实例;这里有用到 EnumMap 详细用法可以参考这篇文章
【数据结构】⭐️基于枚举类型容器的使用-EnumMap-CSDN博客

@Component
public class StrategyFactory implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;

    public static Map<CardTypeEnum,AbstractOcrStrategy> OCR_STRATEGY_MAP = new EnumMap<>(CardTypeEnum.class);

    @Override
    public void afterPropertiesSet() {
        Map<String, AbstractOcrStrategy> ocrStrategyMap = applicationContext.getBeansOfType(AbstractOcrStrategy.class);
        ocrStrategyMap.values().forEach(e-> OCR_STRATEGY_MAP.put(e.getCardEnum(),e));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext= applicationContext;
    }
}

💞️三、测试

        本地测试的话就直接传一个需要识别的图片地址即可(也可以改动下代码,支持传入图片链接,通过 url 获取图片),这里在网上找了一个证件图片(小伙伴们要注意保护好隐私),测试下:

        传入两个参数,一个是图片地址,另一个是该图片对应的卡类型,通过策略工厂获取对应的策略类处理任务,对比下,提取的信息都正确

 🍻四、章末

       这里只是简单实现了图片的信息提取,当然因为本地测试可直接获取到图片文件;也可以改造下支持传递图片,比如url链接或者其他方式,都很方便;另外也可以加入一些新的卡类型,但是要注意新增卡类型后对识别出的结果要做信息提取,用正则提取的时候注意调试。

        文章到这里就结束了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

先锋 Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值