不到100行代码搞定Python做OCR识别身份证,文字等各种字体

2020-10-26 11:10:13 浏览数 (1)

不告诉你我用了它配合Python简简单单开发OCR识别,带你识别手写体、印刷体、身份证等N种,附代码!

文章目录

  • 不告诉你我用了它配合Python简简单单开发OCR识别,带你识别手写体、印刷体、身份证等N种,附代码!
  • 一、你心目中的OCR
  • 二、成果展示
    • (一)手写体成果展示
    • (一)印刷体成果展示
    • (三)名片识别成果展示
    • (四)身份证(同样是模板)成果展示
    • (五)表格识别成果展示:
    • (六)整题识别成果展示:
  • 三、前期准备
  • 四、开发过程手把手,手拉手教给你
    • (一)开发界面
    • (二)ocr_files方法
    • (二)get_ocr_result方法
    • (三)识别普通文字的功能开发
    • (四)识别纸等的功能开发
    • (五)识别表格的功能开发
    • (六)识别题的功能开发
    • (七)get_sign_and_salt方法签名信息等
  • 五、总结

一、你心目中的OCR

在你心目中,OCR是多大(…, 厉害,好厉害,非常厉害,…)呢?

是这么大:

还是这么大:

反正在我心中就和马云爸爸一样这么大。

不管多大了,一块来履行我之前的承诺连更一个月之内,把几篇写完。

序号

预计完成时间

开发dome名字以及功能&发布文章内容

是否已写完

文章链接

1

9月3

文本翻译,单文本翻译,批量翻译demo。

已完成

CSDN:https://blog.csdn.net/qq_17623363/article/details/108511541微信公众号:https://mp.weixin.qq.com/s/6AMzkTtPKf4JcATHD-_yAg

2

9月11

OCR-demo,完成批量上传识别;在一个demo中可选择不同类型的OCR识别《包含手写体/印刷体/身份证/表格/整题/名片),然后调用平台能力,具体实现步骤等。

已完成

CSDN:微信公众号:

3

10月27

语音识别demo,demo中上传—段视频,并截取视频中短语音识别-demo的一段音频进行短语音识别

CSDN:微信公众号:

4

9月17

智能语音评测-demo

CSDN:微信公众号:

5

9月24

作文批改-demo

CSDN:微信公众号:

6

9月30

语音合成-demo

CSDN:微信公众号:

7

10月15

单题拍搜-demo

CSDN:微信公众号:

8

10月20

图片翻译-demo

CSDN:微信公众号:

二、成果展示

最近工作中涉及到一部分文档和纸质文档的校验工作,就想把纸质文件拍下来,用文字来互相校验。想到之前调用有道智云接口做了文档翻译。看了下OCR文字识别的API接口,有道提供了多种OCR识别的不同接口,有手写体、印刷体、表格、整题识别、购物小票识别、身份证、名片等。干脆这次就继续用有道智云接口做个小demo,把这些功能都试了试,当练手,也当为以后的可能用到的功能做准备了。

(一)手写体成果展示

(一)印刷体成果展示

(三)名片识别成果展示

这里我找来了一个名片模板,看起来准度还是可以的

(四)身份证(同样是模板)成果展示

(五)表格识别成果展示:

(这超长的json, >_< emmm…)

(六)整题识别成果展示:

(公式识别也有做,识别结果json比较长,看起来没那么直观,就不在这里贴了)。

三、前期准备

首先,是需要在有道智云的个人页面上创建实例、创建应用、绑定应用和实例,获取到应用的id和密钥。具体个人注册的过程和应用创建过程详见上面列表中的第一篇文章哦。

四、开发过程手把手,手拉手教给你

下面介绍具体的代码开发过程:

这次的demo使用python3开发,包括maindow.pyocrprocesser.pyocrtools.py三个文件。 界面部分,为了简化开发过程,使用python自带的tkinter库,提供选择待识别文件识别类型展示识别结果的功能ocrprocesser.py根据所选类型调用相应api接口,完成识别过程并返回结果;ocrtools.py封装了经整理后的有道ocr 的各类api,实现了分类调用。

(一)开发界面

界面部分代码如下,使用了tkinter的grid来排列元素

代码语言:javascript复制
root=tk.Tk()
root.title("netease youdao ocr test")
frm = tk.Frame(root)
frm.grid(padx='50', pady='50')

btn_get_file = tk.Button(frm, text='选择待识别图片', command=get_files)
btn_get_file.grid(row=0, column=0,  padx='10', pady='20')
text1 = tk.Text(frm, width='40', height='5')
text1.grid(row=0, column=1)

combox=ttk.Combobox(frm,textvariable=tk.StringVar(),width=38)
combox["value"]=img_type_dict
combox.current(0)
combox.bind("<<ComboboxSelected>>",get_img_type)
combox.grid(row=1,column=1)

label=tk.Label(frm,text="识别结果:")
label.grid(row=2,column=0)
text_result=tk.Text(frm,width='40',height='10')
text_result.grid(row=2,column=1)

btn_sure=tk.Button(frm,text="开始识别",command=ocr_files)
btn_sure.grid(row=3,column=1)
btn_clean=tk.Button(frm,text="清空",command=clean_text)
btn_clean.grid(row=3,column=2)

root.mainloop()
123456789101112131415161718192021222324252627

(二)ocr_files方法

其中btn_sure绑定事件ocr_files()文件路径识别类型传入ocrprocesser:

代码语言:javascript复制
def ocr_files():
    if ocr_model.img_paths:
        ocr_result=ocr_model.ocr_files()
        text_result.insert(tk.END,ocr_result)
    else :
        tk.messagebox.showinfo("提示","无文件")
123456

ocrprocesser中主要方法为ocr_files(),将图片base64处理后调用封装的api。

代码语言:javascript复制
def ocr_files(self):
    for img_path in self.img_paths:
        img_file_name=os.path.basename(img_path).split('.')[0]
        #print('===========' img_file_name '===========')
        f=open(img_path,'rb')
        img_code=base64.b64encode(f.read()).decode('utf-8')
        f.close()
        print(img_code)
        ocr_result= self.ocr_by_netease(img_code, self.img_type)
        print(ocr_result)
        return ocr_result
1234567891011

(二)get_ocr_result方法

经本人通读整理有道api的文档,大致分为以下四个api入口:手写体/印刷体识别、身份证/名片识别、表格识别、整题识别,每个接口的url不同,请求参数也不全一致,因此demo中首先根据识别类型加以区分:

代码语言:javascript复制
# 0-hand write
# 1-print
# 2-ID card
# 3-name card
# 4-table
# 5-problem
def get_ocr_result(img_code,img_type):
    if img_type==0 or img_type==1:
        return ocr_common(img_code)
    elif img_type==2 or img_type==3 :
        return ocr_card(img_code,img_type)
    elif img_type==4:
        return ocr_table(img_code)
    elif img_type==5:
        return ocr_problem(img_code)
    else:
        return "error:undefined type!"
1234567891011121314151617

(三)识别普通文字的功能开发

而后根据接口所需的参数组织data等字段,并针对不同接口的返回值进行简单解析和处理,并返回:

代码语言:javascript复制
def ocr_common(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocrapi'
    data = {}
    data['detectType'] = '10012'
    data['imageType'] = '1'
    data['langType'] = 'auto'
    data['img'] =img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    response=do_request(YOUDAO_URL,data)['regions']
    result=[]
    for r in response:
        for line in r['lines']:
            result.append(line['text'])
    return result
123456789101112131415

(四)识别纸等的功能开发

代码语言:javascript复制
def ocr_card(img_code,img_type):
    YOUDAO_URL='https://openapi.youdao.com/ocr_structure'
    data={}
    if img_type==2:
        data['structureType'] = 'idcard'
    elif img_type==3:
        data['structureType'] = 'namecard'
    data['q'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    return do_request(YOUDAO_URL,data)
1234567891011

(五)识别表格的功能开发

代码语言:javascript复制
def ocr_table(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocr_table'
    data = {}
    data['type'] = '1'
    data['q'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    return do_request(YOUDAO_URL,data)
12345678

(六)识别题的功能开发

代码语言:javascript复制
def ocr_problem(img_code):
    YOUDAO_URL='https://openapi.youdao.com/ocr_formula'
    data = {}
    data['detectType'] = '10011'
    data['imageType'] = '1'
    data['img'] = img_code
    data['docType'] = 'json'
    data=get_sign_and_salt(data,img_code)
    response=do_request(YOUDAO_URL,data)['regions']
    result = []
    for r in response:
        for line in r['lines']:
            for l in line:
                result.append(l['text'])
    return result
123456789101112131415

(七)get_sign_and_salt方法签名信息等

get_sign_and_salt()为data加入了必要的签名等信息:

代码语言:javascript复制
def get_sign_and_salt(data,img_code):
    data['signType'] = 'v3'
    curtime = str(int(time.time()))
    data['curtime'] = curtime
    salt = str(uuid.uuid1())
    signStr = APP_KEY   truncate(img_code)   salt   curtime   APP_SECRET
    sign = encrypt(signStr)
    data['appKey'] = APP_KEY
    data['salt'] = salt
    data['sign'] = sign
    return data
1234567891011

五、总结

总的而言,功能还是很强大的,各种都支持。就是视觉算法工程师没有做分类功能,需要自己分别对每一类的图像进行分接口调用,而且接口完全不可混用,比如在开发过程中我将名片图片当作身份证提交给api,结果返回了“Items not found!”,对于调用api的开发者来讲有点麻烦,当然这样也在一定程度上提高了识别准确率,而且个人猜测应该也是为了方便分接口计费 : P。

项目地址:https://github.com/LemonQH/WordPicsOCRDemo

0 人点赞