房产证的 OCR 识别

客户需求,识别一些证件内容,包括身份证、户口本、营业执照、银行卡以及房产证,前四个比较容易实现,不管是艺赛旗的 RPA 还是百度的 OCR 都有接口,直接调用即可,但是都没有房产证的 OCR 识别,只能自己使用其他 OCR 接口来进行相关操作了。
房产证如下图所示:
房产证的 OCR 识别

如果使用通用文字识别所有的文字都可以识别出来,但是顺序是乱的,所以我选择了使用通用文字识别(高精度含位置版),这样的话,我不仅可以识别到文字,还能知道文字所在的位置,然后根据文字位置进行区域划分,划分后的效果如下:
房产证的 OCR 识别

代码如下:

import base64
import copy
import re

import requests


class OCR(object):
    # client_id 为官网获取的AK, client_secret 为官网获取的SK
    client_id = ""
    client_secret = ""

    def get_token(self):
        """获取 access_token"""
        host = 'https://aip.baidubce.com/oauth/2.0/token'

        # 请求头
        headers = {'Content-Type': 'application/json; charset=UTF-8'}

        # 请求参数
        params = {
            "grant_type": "client_credentials",
            "client_id": self.client_id,
            "client_secret": self.client_secret
        }

        # get 请求
        response = requests.get(host, headers=headers, params=params)

        # 获取 json 内容
        content = response.json()

        # 获取 access_token
        access_token = content["access_token"]
        return access_token

    def encode_img(self, img_path):
        """对图片进行编码"""
        with open(img_path, "rb") as f:
            img_content = f.read()
        # 对图片进行 base64 编码
        img_content = base64.b64encode(img_content)
        return img_content

    def img_to_str(self, img_path):
        """对图片文字进行识别"""
        access_token = self.get_token()
        # 请求 URL
        URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=" + access_token

        # post 请求头
        headers = {"Content-Type": "application/x-www-form-urlencoded"}

        # post 参数
        data = {
            "image": self.encode_img(img_path),
            "recognize_granularity": "big"
        }

        # post 请求
        response = requests.post(URL, headers=headers, data=data)

        return response.json()


if __name__ == '__main__':
    ocr = OCR()
    img = "./imgs/fcz_01.jpg"
    str_json = ocr.img_to_str(img)
    my_str_list = str_json["words_result"]
    my_title = ["证明权利或事项", "权利人(申请人)", "义务人", "坐落", "不动产单元号", "其他", "附记"]
    column_line = 999999999
    my_word_list = []
    for data in my_str_list:
        my_list = []
        words = data["words"]
        width = data["location"]["width"]
        top = data["location"]["top"]
        left = data["location"]["left"]
        height = data["location"]["height"]
        my_list.append(words)
        my_list.append(width)
        my_list.append(top)
        my_list.append(left)
        my_list.append(height)
        my_word_list.append(my_list)
        if "不动产证明" in words:
            top_01 = top
            height_01 = height
        if "证明权利或事项" in words:
            top_02 = top
        if words in my_title:
            column_line = left + width if left + width < column_line else column_line
    row_line = (top_01 + top_02 + height) / 2

    head_list = []
    left_list = []
    right_list = []
    for data in my_word_list:
        if data[0] in my_title:
            continue
        if data[2] < row_line:
            head_list.append(data)
        elif data[3] < column_line:
            for i in my_title:
                data[0] = re.sub(i, "", data[0])
            right_list.append(data)
        else:
            right_list.append(data)

    # head 处理
    head_dict = {}
    left = 0
    for data in head_list:
        head_dict[data[3]] = data[0]

    # 排序
    head_dict = sorted(head_dict.items(), key=lambda x: x[0])

    head_str = ""
    for data in head_dict:
        head_str += data[1]
    print(head_str)

    # right 处理
    right_dict = {}
    other_list = copy.deepcopy(right_list)
    for i in range(len(my_title) - 2):
        right_dict[my_title[i]] = right_list[i][0]
        other_list.remove(right_list[i])
    right_dict[my_title[-1]] = right_list[-1][0]
    other_list.remove(right_list[-1])

    # 其他处理
    other_str = ""
    for data in other_list:
        if ":" in data[0]:
            other_str += ";"
        other_str += data[0]
    right_dict[my_title[-2]] = other_str[1:]

    print(right_dict)

运行效果如下:

冀(2019)**市不动产证明第00***19号
{'证明权利或事项': '抵押权', '权利人(申请人)': '中国**************分行', '义务人': '***', '坐落': '路南区*************号', '不动产单元号': '130202*************0118', '附记': '业务编号:20190**20', '其他': '产权证书号:冀(2019)**市不动产权第00****2号;抵押物类型:土地和房屋;抵押方式:一般抵押;担保债权数额:60.00万元;债权起止时间:2019年10月24日起2049年10月24日止'}