图片转文字—百度OCR实现图像识别

2019年5月6日 Jerry 7121 2019年7月16日

        OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程。

        利用OCR api 可以轻松实现图片中文字的提取。目前比较成熟的 OCR api 有百度、搜狗、有道等。这里玩玩百度,简单的几行代码就可以对接百度,从而实现简单的文字提取。关于百度OCR的介绍看 官网

一、创建应用

       需要在官网上创建一个自己的应用,填写应用名称、类型、应用描述等就可以。

       创建成功后在应用列表可以看到刚刚创建的,我们过会需要这里面的两个key

二、获取 access_token

       查看 提供的API文档,可以看到在调用api识别接口之前,需要获取一个access_token。获取方式也很简单,对一个固定的url传入我们应用的 apikey secretkey 即可。

        一个简单的获取 token 的函数便诞生了:

def get_token():
    token_url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=xxxxxxxxxxxxxx&client_secret=yyyyyyyyyyyyyyyyyyyyyyyy' 
    try:
        token_res = requests.get(token_url)
    except:
        return 'error'
    else:
        try:
            print(token_res.text)
            res = token_res.json()["access_token"]
        except:
            return 'error'
        else:
             return res

服务器返回的JSON文本参数如下:我们取其中的 access_token 字段即可。

  • access_token: 要获取的Access Token;
  • expires_in: Access Token的有效期(秒为单位,一般为1个月);
  • 其他参数忽略,暂时不用;

三、获取图片64编码

       查看api文档,通用文本识别需要我们将图片的base64编码传入,于是又诞生了获取图片编码的函数。

def get_pic64():
    try:
        with open ('./test.png','rb') as pic:
            img64 = base64.b64encode(pic.read())
    except:
        return 'error'
    else:
        return img64

四、传入百度api解析

简单的请求参数如下:

HTTP 方法:POST

请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic

URL参数:

参数
access_token 通过API Key和Secret Key获取的access_token

Header如下:

参数
Content-Type application/x-www-form-urlencoded

Body中放置请求参数,参数如下:

参数 是否必选 类型 可选值范围 说明
image 和url二选一 string - 图像数据,base64编码
url 和image二选一 string - 图片完整URL
language_type false string CHN_ENG、ENG、
POR、FRE、
GER、ITA、
SPA、RUS、
JAP、KOR
识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语
detect_direction false string true、false 是否检测图像朝向,默认不检测,即:false。
detect_language false string true、false 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语)
probability false string true、false 是否返回识别结果中每一行的置信度

返回参数如下:

字段 是否必选 类型 说明
direction int32

图像方向,当detect_direction=true时存在。
- -1:未定义,
- 0:正向,
- 1: 逆时针90度,
- 2:逆时针180度,
- 3:逆时针270度

log_id uint64 唯一的log id,用于问题定位
words_result array() 识别结果数组
words_result_num uint32 识别结果数,表示words_result的元素个数
+words string 识别结果字符串
probability object 识别结果中每一行的置信度值
language false int32 当detect_language=true时存在

于是,我们可以构造post请求,具体的参数格式参照api的要求。得出的函数如下:

def get_ocr(token,img64):
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    params = {"image": img64}
    url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=' + token
    res = requests.post(url, data=params, headers=headers)
    try:
        num = res.json()["words_result_num"]
        text = res.json()["words_result"]
    except:
        print("Json ERR")
    else:
        print("识别到结果共计: " + str(num))
        for i in text:
            print(i['words'])

返回结果同样是json数据,我们取其中的字段数[words_result_num]和具体字段[words_result]即可。

实现效果:

要识别的图:

识别结果:

       哈哈,通用版本貌似精度不是很高?没关系,百度okr还提供了高精度识别、含位置的高精度识别等等,换个高精度url试一试:

       卧槽?果然高精度识别更吊一些~!

       其次,百度还提供了针对不同场景的识别:手写文字识别、身份证、银行卡、营业执照、护照、名片、户口本等等,各位老哥自己可以试试。如果有机会,博主想集成一个网页识别到博客里,这样就可以更方便的操作了。

       (插句题外话,关于python的枚举代码)

from enum import IntEnum

class OCR_TYPE(IntEnum):
    general_basic      =1,       #通用文字识别
    accurate_basic     =2,       #通用文字识别(高精度版)
    general_enhanced   =3,       #通用文字识别(含生僻字版)
    handwriting        =4,       #手写文字识别
    idcard             =5,       #身份证识别
    bankcard           =6,       #银行卡识别

if __name__ == '__main__':
    for i in OCR_TYPE:
        print(i.name,'->',i.value)
   print(OCR_TYPE['handwriting'].value)

最后附上完整源码,改下clientID 和 clientKey 即可。

# coding:utf-8
import requests
import base64

#修改为你申请的app参数
AppKey = 'HGXnQTTvk3mTeP1Fk3mOgdbI'
SecretKey = '4e7U2tOmEAhKfqirIKMgEzbOy1ChlOsK'

def get_token():
    token_url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + AppKey+ '&client_secret=' + SecretKey 
    try:
        token_res = requests.get(token_url)
    except:
        return 'error'
    else:
        try:
            print(token_res.text)
            res = token_res.json()["access_token"]
        except:
            return 'error'
        else:
             return res


def get_pic64():
    try:
        with open ('./test.png','rb') as pic:
            img64 = base64.b64encode(pic.read())
    except:
        return 'error'
    else:
        return img64


def get_ocr(token,img64):
    print(token)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    params = {"image": img64}
    #通用识别版本
    #url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=' + token
    #高精度识别版本
    url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=' + token
    res = requests.post(url, data=params, headers=headers)
    try:
        num = res.json()["words_result_num"]
        text = res.json()["words_result"]
    except:
        print("Json ERR")
    else:
        print("识别到结果共计: " + str(num))
        for i in text:
            print(i['words'])

if __name__ == '__main__':

    token = get_token()
    if (token == 'error'):
        print("Get token Err!")
        exit(0)
    img64 = get_pic64()
    if (token == 'error'):
        print("Get img Err!")
        exit(0)

    get_ocr(token, img64)
  

       最后,博主自己基于百度OCR的开发的图片文字提取工具,可识别普通文本、手写文本、身份证、银行卡、护照、营业执照、车牌等。链接:https://www.jerrycoding.com/tool/ocr-ui


原创文章,转载请注明出处: https://jerrycoding.com/article/baidu-ocr

微信
jerry微信赞助
支付宝
jerry支付宝赞助

您尚未登录,暂时无法评论。请先 登录 或者 注册

0 人参与 | 0 条评论