当前位置 博文首页 > cungudafa的博客:百度接口(1)小票识别+票体主题内容处理

    cungudafa的博客:百度接口(1)小票识别+票体主题内容处理

    作者:[db:作者] 时间:2021-09-08 10:26

    一、申请百度接口

    1. 注册百度账号
      https://login.bce.baidu.com/

    2. 百度票据识别
      在这里插入图片描述

    3. 领取免费试用
      在这里插入图片描述

    4. 选择通用文字识别,可以看到通过身份证号实名认证后可1000次/月试用,对开发者初调学习用还是很友好的,赞百度。
      在这里插入图片描述

    5. 回到主页可以看到我们已经申请成功了
      在这里插入图片描述

    6. 创建应用
      在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    前者是通过APIkey引入授权,安全方式需要单独配置许可证,这里仅测试,选择不需要。
    在这里插入图片描述
    在这里插入图片描述

    二、根据文档编辑API访问

    查看文档

    文字识别接口

    1.在应用列表、应用详情、可以查看到APIkey和SecretKey
    在这里插入图片描述

    1. (这里用python测试)获取access_token
    # encoding:utf-8
    import requests 
    
    
    # AccessKey = ''
    # SecretKey = ''
    
    # client_id 为官网获取的AK, client_secret 为官网获取的SK
    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)
    

    测试图片:(来源于网络)
    请添加图片描述

    图像识别:

    
    # encoding:utf-8
    
    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.识别

    继续领取通用票据的识别接口测试权限
    在这里插入图片描述

    
    # encoding:utf-8
    
    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
    #     print(begin,end)
        # 取居于主体内容部分的中间的购买信息
        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)
    #     print(list)
        return list
    
    

    打印出高度区间,取中间中文部分(已经非常nice了!)
    在这里插入图片描述

    3. 物品分类

    我的需求是需要找到购买的物品是属于什么分类,那么在我已有的分类下去归类小票的购买物资就可:
    在这里插入图片描述

    def _isWhat(words,array):
        for key,value in array.items():
    #         print('\n'+key,end=':')
            if key in words:
                return key
            for batching in value:
    #             print(batching, end=' ')
                if batching in words:
                    return batching
                
        return '其他'
    
    array = {'糖果':{'棒棒糖','糖'},'蔬菜':{'青菜','瓜'},'饮料':{'果汁','可乐','橙汁','牛奶','奶茶'},'薯片':{'乐事'},'蛋糕':{'糕点',"绿豆糕"}}
    
    resultList = []
      for food in wordList:
          type = _isWhat(food,array)
          resultList.append({food,type})
      print(resultList)
    

    文章到这里就结束了,代码的逻辑很简单,需求不复杂;同理:百度的图像识别接口除了小票文字还有物体识别,好比如识别到某一类的物体,根据你的字典去归类区分,可以应用于垃圾分类,物品存储过期提醒,烹饪菜谱推荐等等。

    四、源代码

    # encoding:utf-8
    
    import requests
    import base64
    import json
    import re
    '''
    通用票据识别
    '''
    
    def getToken(AccessKey,SecretKey):
        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        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:
    #         print (json.dumps(response.json(),indent=1,ensure_ascii=False))
            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
    
    下一篇:没有了