在使用 PaddleOCR 对身份证图片进行 OCR 识别时,识别到的文本是一块一块的,并且是乱序的
现在识别到的文本块列表是这样的: ['姓名张小明', '出生 1997 年 2 月 7 日', '性别男', '民族汉','荣街金明路 12', '住址', '河南省平顶山市卫东区繁', '号', '公民身份号码', '410221199702071234']
同时还有每个文本块对应的四个点的坐标信息,如: [[283.0,581.0],[396.0,573.0],[398.0,613.0],[285.0,620.0]]
为了后续的关键信息提取更方便,现在想对文本块先进行排序处理
根据坐标信息,如何对文本块按照从上到下从左到右的顺序进行排序?
比如示例的数据,排序后预期应该输出如下: ['姓名张小明', '性别男', '民族汉','出生 1997 年 2 月 7 日', '住址', '河南省平顶山市卫东区繁', '荣街金明路 12', '号', '公民身份号码', '410221199702071234']
或者有没有其他更好的思路?
1
woodfizky 2023-10-24 17:30:42 +08:00
反过来想,姓名、民族、性别、身份证号码,这些格式都是固定的,可以固定判断拿出来。
剩下的就是住址,按 x 坐标排序后拼接得到原始住址。 |
2
woodfizky 2023-10-24 17:33:13 +08:00
另外,没用过这个 OCR ,但是一般 OCR 不都是同一行是一块文本吗,而且为什么你这里的符号被干掉了。。
|
3
noyidoit 2023-10-24 17:36:41 +08:00
调公有云身份证 OCR 接口,直接从 key-value 的响应里取值 XD ;这个提取出来的文本块列表感觉有点太乱了,而且对少数民族身份证可能会支持不太友好
|
4
edward1987 2023-10-24 17:38:57 +08:00
先自己裁切每一部分图片后再去识别,地址的话就分两行两部分识别
|
6
qinyui OP @woodfizky 现在麻烦的就是识别出来的地址文本是被拆分的,并且”姓名“和名字有时也是分开的,还有性别民族等文本的干扰,直接提取是很难区分的
|
7
qinyui OP @edward1987 是个思路,就是实现成本有些高,需要先裁剪出身份证图片再定位每个区域,精度可能会是个问题,还有分多次识别的话整体速度也可能会变慢
|
9
mMartin 2023-10-25 09:12:37 +08:00
paddleocr 有 ser 啊 自动对应关系的
|
10
mMartin 2023-10-25 09:13:42 +08:00
关键信息提取 paddleocr 本身就支持的 尤其是身份证这种场景简单的
|
11
mMartin 2023-10-25 09:22:38 +08:00
|
12
tarasha 2023-10-25 11:24:54 +08:00
我也是用的百度的 ocr-kie 。kie 可以将识别出的文本分类,例如:
{'NAME_KEY': [], 'NAME_VALUE': ['姓名张三'], 'SEX_KEY': ['性别男民族汉'], 'SEX_VALUE': [], 'NATION_KEY': [], 'NATION_VALUE': []} 唯一需要排序的场景是地址的提取,因为地址可能会换行。 我的办法是通过对比地址和证件号码的位置关系,确定照片的角度是哪一种,然后再依据每种角度来排序 0°:左上角 Y 点从小到大 90°:左上角 X 点从大到小 180°:左上角 Y 点从大到小 270°:左上角 X 点从小到大 # points 结构为 [[左上角 X, 左上角 Y], [右上角 X, 右上角 Y], [右下角 X, 右下角 Y], [左下角 X, 左下角 Y]] # X 从左至右增大,Y 从上至下增大 # 计算地址文本块水平宽度 右上角 X - 左上角 X x_length = address_points[1][0] - address_points[0][0] # 计算地址文本块垂直高度 左下角 Y - 左上角 Y y_length = address_points[3][1] - address_points[0][1] # 判断图片是否水平 # 若地址文本块水平宽度大于垂直高度则说明图片处于 0°或 180°,否则处于 90°或 270° is_horizontal = x_length > y_length # 判断图片是否反转 # 若水平且地址文本块左上角 Y 点大于证件号码文本块左上角 Y 点 (即地址位于号码下方)则处于 180° # 若非水平且地址文本块左上角 X 点大于证件号码文本块左上角 X 点 (即地址位于号码右侧),则处于 90° is_reverse = (is_horizontal and address_points[0][1] >= number_points[0][1]) or \ (not is_horizontal and address_points[0][0] >= number_points[0][0]) # 执行排序 sorted_address_data = sorted( address_data, reverse=is_reverse, key=lambda x: x['points'][0][1 if is_horizontal else 0], ) |
13
rev1si0n 2023-10-25 13:15:40 +08:00
PaddleOCR 应该会返回文字对应坐标的吧,根据坐标对应不就行了吗
|
15
tarasha 2023-10-25 13:57:09 +08:00
@qinyui 还是需要训练下的,需要自定义字典文件。也就是分类。看下这个:
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7/doc/doc_ch/kie.md |
17
NoOneNoBody 2023-10-25 14:00:49 +08:00
身份证这种格式都是固定的图片,且跨时间长度和跨项目的,可以用固定参数来写就好了
可以前置一个标准化步骤,把输入的图片旋转、裁切、缩放到固定的尺寸和方向 |