开发者学堂课程【达摩院视觉AI课:文字识别项目讲解及使用说明】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/335/detail/3835
文字识别项目讲解及使用说明
借助阿里云视觉智能平台提供的能力,实现简单的身份证识别系统,首先查看系统的功能呈现和界面呈现
身份证识别系统的初始界面,需要上传人像面和国徽面,上传,选定图片后,点击开始识别
后台将身份证识别的信息以及上传的身份证照片返回,是一个简单身份证识别的系统
介绍系统实现的核心逻辑以及如果使用SDK、OCR及其他其他java能力
项目的整个结构,打开src java包,项目是通过StringBootStructure创建的一个StringBoot项目,Application是StringBoot的启动类
Control是控制器层,负责模板的渲染、路由等
OcrServive负责调用视觉智能开发平台的ocr能力,通过sdk调用,resources中index基于templates做的前端的模板,可以根据数据情况动态地渲染,properties是一个包含若干配置的配置文件,配置含义稍后会具体介绍
查看pom依赖
依赖若干个stringboot相关的依赖项,主要是string-boot-starter以及thymeleaf的依赖,以及string-boot单元测试的依赖
下面是Apache提供的commons包,用到其中通用的函数、通用的方法
org.apache.commons
下面是视觉智能开放平台提供的ocr的sdk
com.aliyun
ocr
1.0.3
下面是fastjson,项目中用到了json的处理
com.alibaba
fastjson
1.2.67
重点查看视觉智能开放平台提供的sdk如何获取、如何使用
找到ocr的sdk,进入视觉智能开放平台官网,vision.aliyun.com
上新很多视觉智能开放平台的AI能力
找到文字识别、身份证识别,进入,查看产品文档,文档中主要看SDK部分,SDK参考,因为文件对java来说提供两种SDK,第一种是通用的SDK,有一些要求,调用AI算法时,需要提供OSS的URL,先把图片上传到OSS中,拿到图片的URL,才能调用SDK
另外新版的java的SDK,支持本地上传,通过此SDK可以直接将本地的文件交给视觉智能开放平台进行OCR的识别以及人脸识别等调用AI能力
里面有很多产品的SDK,需要找到OCR的SDK调用给出了一个样例,需要ocr的version找到最新版的SDK
com.aliyun
ocr
${aliyun.ocr.versiony
可以通过下方说明的连接找到http://mvnrepository.com/artifact/com.aliyun
复制链接打开加上ocr
输入验证码
可以看到ocr产品sdk进行若干次升级,目前代码使用的版本是1.0.3
Main坐标是在代码中使用的坐标
以上是如何获取视觉智能开放平台的SDK方法
整个项目的实现逻辑与需要注意的点或方法
回到代码中,首先查看基于template做的前端模板
模板页面上面是标题,下面是表单,提供两个上传文件的组件,旁边有一个按钮
代码中
VIAPI RecognizeIdentityCard Example
是一个标题
下面是有一个表单
表单中有两个文件上传的按钮,两个并列的上传人像面和上传国徽面的按钮
借用bootstrap和script能力
http://apps.dbimg.com/libs/jquery/2.1.4/jquery.min.js</a>”>
实现美化界面的作用
Div中实际展示了基于bootstrap绘制上传了一个组件,通过代理input框实现美化的作用,相当于点击这一层将文件上传到input组件,将input组件中的内容传给form表单,提交
<div class=”col-sm-4”>
<div class=”input-group”>
<input id=’location’ class=”from-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>
下方文件上传的按钮是同样的操作
可以看到文件上传的类型.jpg、.png、.jpeg
Input框是file类型,但是display设置为now,相当于是一个原生的input框,上面基于bootstrap绘制的input框,是真正展示的样式,有一个onclick事件,通过i-face id找到input组件,onclick事件相当于点到input组件,是input组建的们门面
开始识别
是一个提交的按钮,能注意到有一个alert的message,相当于作用提示客户上传的有问题,报错之类的,会展示出来,信息不为空会展示,否则不展示
上传完数据、图片进行身份证识别拿到这真正识别数据之后进行的展示
对两张上传数据进行展示,使用img标签,faceiamge与backimage是后端返回的文件,图片返回的地址使用template语法,图片不为空时,展示出来
展示身份证识别的文字结果,使用识别结构不为空时展示出来,正面照片有姓名、性别、民族、出生年月、住址、身份证号码,背面有签发机关和有效日期
以上是前端页面的结构和实现的逻辑点
介绍控制器层,在maincontroller中用controller以及stringboot提供的加了注解
定义了若干个成员和变量
public class MainController {
private string uploadDirectory;
private OcrService ocrService;
private List facelmages;
private List backImages;
private List> faceResults;
private List> backResults;
UploadDirectory定义上传文件,本地保存的地址
ocrService提供调用视觉智能开放平台ocr能力的一层封装
faceImage与backImage缓存之前上传图片的路径地址,faceResults与backResults是缓存之前的识别结果,faceImage、backImage、faceResults与backResults四个变量因为需要使用数据库,在内存中缓存上传图片和识别结果的信息,
public NainController(@value("$(file.upload.path)") String uploadDirectory,ocrService ocrservice) {
this.uploadlDirectory =uploadDirector;
this.ocrServiee = oerservice;
faceImages =new ArrayList<>();
baceImages =new ArrayList<>();
faceResults =new ArrayList<>();
baceResults =new ArrayList<>();
}
是一个构造方法
Upload.path在配置文件中
Spring.servlet.muiltipart.max-file-size=100MB
File.upload.path=/Users/ioffcs/home/code/viapi-demo/target/classes/static/images/
Viapi.accessKeyId=xxx
Viapi.accessKeySecret=xxx
配置文件是本机的一个目录,在实际操作时替换成自己电脑的目录
上传文件地址配置的目录,前面是用户目录,viapi-demo是项目的更目录classes、static下面的images目录,stringboot默认取static目录作为静态文件的一个地址,地址来自于resources目录下的statics目录,将静态文件放在目录下,会根据相对路径取文件的地址
是源码中的目录,编译完成后,变成下方目录
Target、classes、com、static,templates对应上面templates是前端模板文件,static对应上面static,静态文件地址,将文件地址配置到static目录下,stringboot默认取静态文件的地址,没有做静态文件的代理,将文件地址之间配置到static,将文件上传到static目录下,方便文件存储和读取操作,images是相对static自定义的一个目录,对目录下存放图片类的数据,将地址替换为自己本机的就可以
回到controller中
Save方法保存文件
有两个控制方法index与uploadFile
页面初始通过图片方法加载模板
@RequestMapping()
public string index (Model model){
if(faceImages.size() I=backImaes.size()){
faceImages.clear();
backImages.clear();
faceResults.clear();
backResults.clear();
异常情况下两张缓存图片不一样,修改,不断完善
if(!collectionUtils.isEmpty(faceImages)&&faceImages.size()== backImages.size ()){
model.addAttribute( s: "faceImage",faceImages.get(faceImages.size()-1));
model.addAttribute(s: "faceResult", faceResults.get(faceResults.size()- 1))
model,addAttribute( s: "backImage",backImagee.get(backImages.size()- 1));
model.addAttribute( s: "backResult",backResults.get(backResults.size()- 1))1
}
retorn"index";
如果有上传过图片,成功识别后,将前一次上传的结果以及识别的结果加载到首页中,重新刷新页面,之前上传和识别结果不会丢失,展示在页面上
上传文件的控制方法,接收face,类型是multipartFile,正面是人像文件,back是封面的一个文件,参数后面也能使用到
首先查看两张图片是否为空,如果为空,重新上传到首页通过index模板访问进入首页,增加一个message,提醒必须上传文件,否则上传是没有作用的,进入逻辑中,查看上传目录是否存在,存在进行递归,创建目录,如果人像面图片不为空,保存到本地
保存通过stringUtils方法,将文件后缀名解出,生成一个UUID的随机文件名,加上后缀,作用防止上传图片是重复的,文件名会将旧的覆盖,复制将文件保存到本地,并且返回文件名
拿到文件名相当于保存成功,调用ocrService身份证识别方法,将文件的完整路径说明,以及说明是人像面照片,拿到返回的一个识别结果
将已经上传的图片加入到缓存池中,将识别结果加入到缓存池中,加images是因为保存目录有images,stringboot默认的保存地址是在static下,相当于images加上文件名就可以保存文件的地址
if(!faee.isEmpty()){
String filename=saveFile(face);
Map res = ocrService.RecognizeIdcard( filePath: uploadDirectory + filename,side: "face")
faceImges.add( "/Images/" +filename);
faceResults.add (res);
}
If (!back.isEmpty ()){
国徽面照片的处理方式也是类似的,参数和保存的地址可能有区别,参数back
下面有异常处理,如果有异常信息,先打出来,然后捕捉,将errormessage加到message,提新用户出错
会对逻辑中,将图片上传的一些信息、结构渲染到界面上,整体是控制器层的实现逻辑
查看ocrService实现逻辑
ocrService有几个变量,ocrClient调用ocr能力时需要client,runtime参数
AccessKeyId与AccessKeySecret
在开通视觉智能开放平台的能力时,会用到阿里云keyId和keySecret,需要配置到配置文件中
配置到自己的keyId和keySecret
有一个初始化方法用strinboot提供postConstruct实现初始化,初始化实现初始config若干信息,通过config信息初始化ocrClient,初始化一个Runtime,Runtime是一个空的对象,需要命名一个空对象,需要在里面调用
查看调用身份证识别的逻辑
调用的RecognizeIdCard方法,有两个参数,filePath和side,filePath是本地文件路径,side是标识身份证正反面信息,需要new一个request,reguest点进去查看代码
Request有两个参数,一个为imageURLObject,接收inputStream,另外一个是side,接收String,有两个值face、side,在官网可以查看
将两个参数复制,files借助工具类new一个inputStream,通过filePath拿到file,将side参数传给request,通过ocrClient调用身份证识别的方法,将request和runtime传给方法,可以拿到一个response,response返回的数据是data,定义有两个result,一个是frontResult,一个是backResult,
如果是正面的,取正面结果,通过发送json转成哈希map结构,反面同理
If("face ".equals(side)){
return JSON.parseObject (JSON.JSONString(response.data. frontResult),new TypeReference>(){})
}else{
return JSON.parseObject(JSON.toJSONString(response.data.backResult),new TypeReforence>() {});
}
Controller层拿到结果加入到结果中,最后做展示
前端代码用到faceResult.name、gender、nationality、birthDate、address、IDNumber,以及背面issue、startDate、endDate结果,简化流程用哈希map,sdk定义中有自己的结构定义
Response正面结果定义
有name、gender、nationality、birthDate、address、IDNumber,有刚才字段是相同的,将结构返回到前端,可以根据自己喜好做一些属性,ocrService以这种方式给调用。