一、申请百度接口
-
注册百度账号 https://login.bce.baidu.com/ -
百度票据识别  -
领取免费试用  -
选择通用文字识别,可以看到通过身份证号实名认证后可1000次/月试用,对开发者初调学习用还是很友好的,赞百度。  -
回到主页可以看到我们已经申请成功了  -
创建应用 
  前者是通过APIkey引入授权,安全方式需要单独配置许可证,这里仅测试,选择不需要。  
二、根据文档编辑API访问
查看文档
文字识别接口
1.在应用列表、应用详情、可以查看到APIkey和SecretKey 
- (这里用python测试)获取access_token
import requests
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+AccessKey+'&client_secret='+SecretKey
headers = {
'Content-Type': 'application/json;charset=UTF-8'
}
access_token = ''
response = requests.get(url=host, headers=headers)
if response:
res = response.json()
access_token = res['access_token']
print(access_token)
测试图片:(来源于网络) 
图像识别:
import requests
import base64
'''
通用文字识别
'''
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
f = open('/Users/wangyu/Desktop/xiaopiao.jpg', 'rb')
img = base64.b64encode(f.read())
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
print (response.json())
识别结果:这里是文字识别效果也非常好,和小票拍摄清晰度也有一定关系,比较满意。 
三、小票识别
1.识别
继续领取通用票据的识别接口测试权限 
import requests
import base64
import json
'''
通用票据识别
'''
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/receipt"
f = open('/Users/wangyu/Desktop/xiaopiao.jpg', 'rb')
img = base64.b64encode(f.read())
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
print (json.dumps(response.json(),indent=1,ensure_ascii=False))
打印内容:文字、文字所处的位置 打印出words可以发现识别内容非常鸡肋: 
2.票体内容处理
明显发现识别的信息还是不够具体,图源网络,我们需要对小票内容分析,仅需要 票体:主题内容 即可。  思路:既然有location位置,那么优先以位置信息来定位头和尾部信息,并剔除;找到头部关键字距离顶部的高度top1(如图蓝色),找到底部的关键字距顶部的高度top2(如图黄色),票体的内容部分高度为:top1~top2(如图绿色部分)  关键字的确定:参考多种购物小票的排版,可以发现,头部有通用字样标识符:“单价、数量”,尾部有“总计、应付、合计、应收”等字样,但是像金额、优惠的字样不可取,上下均有出现。  多个关键字去匹配,匹配到的值:顶部取最大值,底部取最小值来精确中间body的高度。我这里还剔除了长数字和英文,因为我不需要单价等细节,直接正则匹配过滤了。
def _isbody(response):
begin,end = 0,999999
beginWords = ["数量","单价","售价","单位"]
endWords = ["总计","总金额","支付","应收","应付","合计"]
for idx in response['words_result']:
for i in beginWords:
if i in idx['words']:
temp = idx['location']['top']
if temp > begin:
begin = temp
for j in endWords:
if j in idx['words']:
temp2 = idx['location']['top']
if temp2 < end:
end = temp2
list = []
for idx in response['words_result']:
top = idx['location']['top']
if top > begin and top < end :
foods = re.sub('[^\u4e00-\u9fa5]', '', idx['words'])
if foods != '':
list.append(foods)
return list
打印出高度区间,取中间中文部分(已经非常nice了!) 
3. 物品分类
我的需求是需要找到购买的物品是属于什么分类,那么在我已有的分类下去归类小票的购买物资就可: 
def _isWhat(words,array):
for key,value in array.items():
if key in words:
return key
for batching in value:
if batching in words:
return batching
return '其他'
array = {'糖果':{'棒棒糖','糖'},'蔬菜':{'青菜','瓜'},'饮料':{'果汁','可乐','橙汁','牛奶','奶茶'},'薯片':{'乐事'},'蛋糕':{'糕点',"绿豆糕"}}
resultList = []
for food in wordList:
type = _isWhat(food,array)
resultList.append({food,type})
print(resultList)
文章到这里就结束了,代码的逻辑很简单,需求不复杂;同理:百度的图像识别接口除了小票文字还有物体识别,好比如识别到某一类的物体,根据你的字典去归类区分,可以应用于垃圾分类,物品存储过期提醒,烹饪菜谱推荐等等。
四、源代码
import requests
import base64
import json
import re
'''
通用票据识别
'''
def getToken(AccessKey,SecretKey):
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+AccessKey+'&client_secret='+SecretKey
headers = {
'Content-Type': 'application/json;charset=UTF-8'
}
access_token = ''
response = requests.get(url=host, headers=headers)
if response:
res = response.json()
access_token = res['access_token']
return access_token
def getResult(url,access_token):
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/receipt"
f = open(url, 'rb')
img = base64.b64encode(f.read())
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
return response.json()
def _isbody(response):
begin,end = 0,999999
beginWords = ["数量","单价","售价","单位"]
endWords = ["总计","总金额","支付","应收","应付","合计"]
for idx in response['words_result']:
for i in beginWords:
if i in idx['words']:
temp = idx['location']['top']
if temp > begin:
begin = temp
for j in endWords:
if j in idx['words']:
temp2 = idx['location']['top']
if temp2 < end:
end = temp2
list = []
for idx in response['words_result']:
top = idx['location']['top']
if top > begin and top < end :
foods = re.sub('[^\u4e00-\u9fa5]', '', idx['words'])
if foods != '':
list.append(foods)
return list
def _isWhat(words,array):
for key,value in array.items():
if key in words:
return key
for batching in value:
if batching in words:
return batching
return '其他'
def main():
url = '/Users/wangyu/Desktop/xiaopiao2.jpg'
AccessKey = ''
SecretKey = ''
access_token = getToken(AccessKey,SecretKey)
response = getResult(url,access_token)
wordList = _isbody(response)
array = {'糖果':{'棒棒糖','糖'},'蔬菜':{'青菜','瓜'},'饮料':{'果汁','可乐','橙汁','牛奶','奶茶'},'薯片':{'乐事'},'蛋糕':{'糕点',"绿豆糕"}}
resultList = []
for food in wordList:
type = _isWhat(food,array)
resultList.append({food,type})
print(resultList)
main()
识别效果: 
|