阿里云高校计划视觉AI五天训练营教程 Day 2 - 身份证识别系统搭建

简介: 借助阿里云视觉开放平台OCR实现身份证识别系统

初始界面

image.png

项目结构

SpringBootApplication——SpringBoot启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class IdCardorcApplication {
    public static void main(String[] args) {
        SpringApplication.run(IdCardorcApplication.class, args);
    }
}

MainController——控制进程

异常情况下clear

if (faceImages.size() != backImages.size()) {
    faceImages.clear();
    backImages.clear();
    faceResults.clear();
    backResults.clear();
    }

刷新页面重新加载已识别结果

 if (!CollectionUtils.isEmpty(faceImages) && faceImages.size() == backImages.size()) {
        model.addAttribute("faceImage", faceImages.get(faceImages.size() - 1));
        model.addAttribute("faceResult", faceResults.get(faceResults.size() - 1));
        model.addAttribute("backImage", backImages.get(backImages.size() - 1));
        model.addAttribute("backResult", backResults.get(backResults.size() - 1));
    }

上传文件判定

public String upload(@RequestParam("face") MultipartFile face, @RequestParam("back") MultipartFile back,
                     RedirectAttributes redirectAttributes) {
    if (face.isEmpty() || back.isEmpty()) {
        redirectAttributes.addFlashAttribute("messages", "请选择一个文件进行上传。");
        return "redirect:/index";
    }
    String errorMessages = null;
    Path dir = Paths.get(uploadDir);
    if (!Files.exists(dir)) {
        try {
            Files.createDirectories(dir);
        } catch (IOException e) {
            e.printStackTrace();
            errorMessages += e.getMessage() + "\n";
        }
    }
    try {
        if (!face.isEmpty()) {
            String filename = saveFile(face);
            Map<String, String> faceResult = ocrService.RecognizeIdCard(uploadDir + filename, "face");
            faceImages.add("/images/" + filename);
            faceResults.add(faceResult);
        }
        if (!back.isEmpty()) {
            String filename = saveFile(back);
            Map<String, String> faceResult = ocrService.RecognizeIdCard(uploadDir + filename, "back");
            backImages.add("/images/" + filename);
            backResults.add(faceResult);
        }
    } catch (Exception e) {
        e.printStackTrace();
        errorMessages += e.getMessage() + "\n";
    }
    if (StringUtils.isNoneBlank(errorMessages)) {
        redirectAttributes.addFlashAttribute("messages", errorMessages);
    }
    return "redirect:/index";
}

存储逻辑

public String saveFile(MultipartFile file) {
    String filename = UUID.randomUUID().toString() + "."
            + StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
    Path path = Paths.get(uploadDir + filename);
    System.out.println(faceResults);
    try {
        Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
        return null;
    }
    return filename;
}

OcrService——通过SDK调用视觉开放平台的OCR

初始化config

private void init() throws Exception {
    Config config = new Config();
    config.endpointType = "access_key";
    config.regionId = "cn-shanghai";
    config.accessKeyId = accessKeyId;
    config.accessKeySecret = accessKeySecret;
    config.endpoint = "ocr.cn-shanghai.aliyuncs.com";

    orcClient = new Client(config);
    runtimeOptions = new RuntimeOptions();
}

调用逻辑

public Map<String, String> RecognizeIdCard(String fielpath, String side) throws Exception {
    RecognizeIdentityCardAdvanceRequest request = new RecognizeIdentityCardAdvanceRequest();
    request.imageURLObject = Files.newInputStream(Paths.get(fielpath));
    request.side = side;
    RecognizeIdentityCardResponse response = orcClient.recognizeIdentityCardAdvance(request, runtimeOptions);
    return "face".equals(side) ?
            JSON.parseObject(JSON.toJSONString(response.data.frontResult), new TypeReference<Map<String, String>>(){})
            : JSON.parseObject(JSON.toJSONString(response.data.backResult), new TypeReference<Map<String, String>>(){});
}

index.html——前端模板

上传界面

<form method="post" th:action="@{/upload}" enctype="multipart/form-data">
    <div class="row">
        <div class="col-sm-4">
            <div class="input-group">
                <input id="location" class="form-control" onclick="$('#i-face').click();">
                <label class="input-group-btn">
                    <input type="button" id="i-check" value="上传人像面" class="btn btn-primary" onclick="$('#i-face').click();">
                </label>
            </div>
        </div>
        <input type="file" name="face" id="i-face" accept=".jpg, .png, .jpeg" onchange="$('#location').val($('#i-face').val());" style="display: none">
        <div class="col-sm-4">
            <div class="input-group">
                <input id="locationf" class="form-control" onclick="$('#i-back').click();">
                <label class="input-group-btn">
                    <input type="button" id="i-checkb" value="上传国徽面" class="btn btn-primary" onclick="$('#i-back').click();">
                </label>
            </div>
        </div>
        <input type="file" name="back" id="i-back" accept=".jpg, .png, .jpeg" onchange="$('#locationf').val($('#i-back').val());" style="display: none">
        <div class="col-sm-4">
            <button type="submit" class="btn btn-primary form-control">开始识别</button>
        </div>
    </div>
</form>

识别后展示

<div class="row" style="margin-top: 38px;">
    <div class="col-md-12 mx-auto">
        <div class="row">
            <div class="col-sm-4">
                <img th:src="${faceImage}" th:if="faceImage != null" class="img-fluid">
            </div>
            <div class="col-sm-4">
                <img th:src="${backImage}" th:if="backImage != null" class="img-fluid">
            </div>
        </div>
    </div>
</div>
<div class="row" style="margin-top: 38px;">
    <div class="col-md-12 mx-auto" th:if="${faceResult != null}">
        <div class="row">
            <div class="col-sm-4">
                <p><span>姓名: </span><span th:text="${faceResult.name}"></span></p>
                <p><span>性别: </span><span th:text="${faceResult.gender}"></span></p>
                <p><span>民族: </span><span th:text="${faceResult.nationality}"></span></p>
                <p><span>出生日期: </span><span th:text="${faceResult.birthDate}"></span></p>
                <p><span>住址: </span><span th:text="${faceResult.address}"></span></p>
                <p><span>身份证号: </span><span th:text="${faceResult.IDNumber}"></span></p>
            </div>
             <div class="col-sm-4">
                <p><span>签发机关: </span><span th:text="${backResult.issue}"></span></p>
                <p><span>有效日期: </span><span th:text="${backResult.startDate}">-<span th:text="${faceResult.endDate}"></span></span></p>
             </div>
        </div>
    </div>
</div>

application.properties——若干配置文件

server.port=
file.uplaod.path=
aliapi.accessKeyId=
aliapi.accessKeySecret=

pom.xml——若干相关依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.10</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.4.8</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.52</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>ocr</artifactId>
        <version>1.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
</dependencies>
相关文章
|
7月前
|
人工智能 监控 安全
提效40%?揭秘AI驱动的支付方式“一键接入”系统
本项目构建AI驱动的研发提效系统,通过Qwen Coder与MCP工具链协同,实现跨境支付渠道接入的自动化闭环。采用多智能体协作模式,结合结构化Prompt、任务拆解、流程管控与安全约束,显著提升研发效率与交付质量,探索大模型在复杂业务场景下的高采纳率编码实践。
765 26
提效40%?揭秘AI驱动的支付方式“一键接入”系统
|
7月前
|
人工智能 新制造
TsingtaoAI受邀参加宁波AI海曙科创训练营并分享技术落地实践
10月12日至15日,由宁波市海曙区组织部主办的AI海曙科创训练营在宁波成功举办。作为受邀企业代表,TsingtaoAI团队深入参与了多项活动,与政府领导、行业专家及科创企业代表围绕AI技术在制造业、成果转化等领域的实际应用展开交流,用真实案例诠释了“技术扎根产业”的价值逻辑。
205 2
|
7月前
|
存储 人工智能 搜索推荐
LangGraph 记忆系统实战:反馈循环 + 动态 Prompt 让 AI 持续学习
本文介绍基于LangGraph构建的双层记忆系统,通过短期与长期记忆协同,实现AI代理的持续学习。短期记忆管理会话内上下文,长期记忆跨会话存储用户偏好与决策,结合人机协作反馈循环,动态更新提示词,使代理具备个性化响应与行为进化能力。
1411 10
LangGraph 记忆系统实战:反馈循环 + 动态 Prompt 让 AI 持续学习
|
7月前
|
机器学习/深度学习 人工智能 JSON
PHP从0到1实现 AI 智能体系统并且训练知识库资料
本文详解如何用PHP从0到1构建AI智能体,涵盖提示词设计、记忆管理、知识库集成与反馈优化四大核心训练维度,结合实战案例与系统架构,助你打造懂业务、会进化的专属AI助手。
1132 6
|
7月前
|
人工智能 JSON 安全
Claude Code插件系统:重塑AI辅助编程的工作流
Anthropic为Claude Code推出插件系统与市场,支持斜杠命令、子代理、MCP服务器等功能模块,实现工作流自动化与团队协作标准化。开发者可封装常用工具或知识为插件,一键共享复用,构建个性化AI编程环境,推动AI助手从工具迈向生态化平台。
2081 1
|
8月前
|
人工智能 机器人 新能源
深化新工科建设 共探智能新未来 | 阿里云支持南京大学苏州校区“AI DAY”盛大启幕丨云工开物
9月12日,南京大学苏州校区举办“AI新视界:深化新工科建设进行式”活动,采用教师与学生双专场模式,通过主题分享、实践演练、产业课题发布等形式,搭建产教融合AI交流平台,助力未来产业科技人才培养。
|
9月前
|
存储 弹性计算 人工智能
阿里云学生“云工开物”优惠福利详解
“云工开物”是阿里云推出的高校计划,面向全国师生提供丰富云资源与优惠权益,助力科研、教学与学习实践。学生完成认证即可领取300元无门槛抵扣金,享受包年包月或按量付费云产品,如低价ECS实例、轻量服务器等,提升云计算技能,低成本、高效开展项目实践。
|
11月前
|
人工智能 智能设计 算法
浙江大学联合阿里云举办的全国高校人工智能师资素养提升交流活动圆满结束丨云工开物
为推动人工智能与教育深度融合,浙江大学联合阿里云举办“2025年全国高校人工智能师资素养提升交流活动”。活动吸引121所高校及单位的579名教师参与,通过项目实例讲解、平台实践训练等方式,助力教师掌握AI技术并融入教学。活动中,浙江大学与阿里云专家分享了前沿技术和应用案例,参访浙大艺博馆与阿里云展厅,并完成AIGC辅助设计实训。未来,双方将持续推进数字化技能培训,支持高校AI人才培养。
|
11月前
|
存储 人工智能 云计算
挑战杯专属支持资源|阿里云-AI大模型算力及实验资源丨云工开物
阿里云发起的“云工开物”高校支持计划,助力AI时代人才培养与科研创新。为“挑战杯”参赛选手提供专属算力资源、AI模型平台及学习训练资源,包括300元免费算力券、百炼大模型服务、PAI-ArtLab设计平台等,帮助学生快速掌握AI技能并构建优秀作品,推动产学研融合发展。访问链接领取资源:https://university.aliyun.com/action/tiaozhanbei。
|
11月前
|
传感器 人工智能 智能设计
邀请大学生用AI技术助力乡村振兴!“挑战杯”阿里云赛题有哪些值得关注?丨云工开物
第十九届“挑战杯”中国青年科技创新“揭榜挂帅”擂台赛——人工智能主擂台赛在上海启动。赛事聚焦城市治理、乡村振兴等领域,由阿里云等企业发榜,提供算力与AI工具支持。其中,“以AI助力乡村振兴”专项赛邀请高校师生围绕浙江开化县、江西遂川县的文化与特产设计文旅产品,推动传统文化与现代技术融合,为乡村振兴注入新活力。赛事现已开放报名,欢迎全国高校师生参与。