您的当前位置:首页正文

OCR 身份证识别

2024-11-10 来源:个人技术集锦

python基于paddleocr docker部署 身份证OCR识别

脚本 文件

# -*- coding: utf-8 -*-
# 1. 导入Flask扩展
from flask import Flask, request
from gevent import pywsgi
from paddleocr import PaddleOCR
from flask_cors import CORS
import logging
import re
from paddleocr import logger


# 2. 创建Flask应用程序示例
# 需传入__name__,作用是为了确定资源所在路径
app = Flask(__name__)
# 解决跨域问题
CORS(app, resources=r'/*')

# Paddleocr目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
ocr = PaddleOCR(use_angle_cls=True, lang="ch")  # need to run only once to download and load model into memory

#默认的warning级别,只输出warning以上的
#使用basicConfig()来指定日志级别和相关信息

logging.basicConfig(level=logging.DEBUG #设置日志输出格式
                    ,filemode="w" #文件的写入格式,w为重新写入文件,默认是追加
                    ,format="%(asctime)s - %(name)s - %(levelname)-9s - %(filename)-8s : %(lineno)s line - %(message)s" #日志输出的格式
                    # -8表示占位符,让输出左对齐,输出长度都为8位
                    ,datefmt="%Y-%m-%d %H:%M:%S" #时间输出的格式
                    )

# 全局异常
@app.errorhandler(500)
def server_error(error):
    return {"code": 500, "message": "未识别到数据"}

# 3. 定义路由及视图函数
# Flask中定义路由是通过装饰器实现
@app.route('/', methods=['GET', 'POST'])
def hello_world():
    return 'Hello, flask!'

# 上传图片进行简单的ocr
@app.route('/simple_ocr', methods=['POST'])
def simple_ocr():
    uploaded_file = request.files['file']
    # 数据列表
    data = list()
    # 名字不为空
    if uploaded_file.filename != '':
        logging.info("文件名字:" + uploaded_file.filename)
        result = ocr.ocr(uploaded_file.stream.read(), cls=False)
        for idx in range(len(result)):
            res = result[idx]
            for line in res:
                logging.info(line)
                # 相似度大于0.8的数据匹配度高
                if line[-1][1] > 0.75:
                    data.append(line[-1][0])
    return {"code": 200, "message": "操作成功", "data": data}

# 上传图片进行身份证的ocr
@app.route('/idcard_ocr', methods=['POST'])
def idcard_ocr():
    uploaded_file = request.files['file']
    # 数据列表
    data = list()
    # 标记位
    flag = True
    # 首位标记位
    first = True
    # 名字不为空
    if uploaded_file.filename != '':
        logging.info("文件名字:" + uploaded_file.filename)
        result = ocr.ocr(uploaded_file.stream.read(), cls=False)
        for idx in range(len(result)):
            res = result[idx]
            for line in res:
                logging.info(line)
                # 相似度大于0.8的数据匹配度高
                if line[-1][1] > 0.75:
                    data.append(line[-1][0])
                    if first:
                        first = False
                        card_name = line[-1][0]
                        # 判断第一行是否包含姓名
                        if "姓名" in card_name:
                            sub = card_name[card_name.index("姓名") + 2:]
                            if len(sub)>1: card_name=sub
                        else:
                            # 第一行没有姓名 直接是名字
                            if len(card_name) > 5 or ( card_name=='居民身份证' or card_name=='中华人民共和国'):card_name=''
                        # print('first', card_name)
                    if flag:
                        is_valid, id_card = validate_id_card(line[-1][0])
                        if is_valid:
                            flag = False

    # 正面
    if len(card_name)>0:
        flag = False
    # 把所有信息筛选获取身份照吗
    if len(card_name) == 0:
        for i in data:
            if "姓名" in i:
                card_name = i[i.index("姓名") + 2:]
                flag = False

    # 身份证的背面为True
    if flag:
        for i in data:
            is_valid, date = validate_date(i)
            if is_valid:
                break
        return {"code": 200, "message": "操作成功", "data": {"source": data, "date": date, "card_side": "back"}}

    return {"code": 200, "message": "操作成功", "data": {"source": data, "id_card": id_card, "id_name":card_name, "card_side": "front"}}

# 身份证校验
def validate_id_card(id_card):
    # 定义身份证号的正则表达式,用于验证格式
    id_card_pattern = r'\d{17}[\dXx]|\d{15}'

    # 使用正则表达式进行匹配
    matches = re.findall(id_card_pattern, id_card)

    # 输出匹配到的身份证号码
    if matches:
        print("身份证号:", matches[0])
        return True, matches[0]
    else:
        return False, ''
    
# 日期校验    
def validate_date(date):
    # 定义日期的正则表达式
    date_pattern = r'\d{4}\.\d{2}\.\d{2}-\d{4}\.\d{2}\.\d{2}'
    
    # 使用正则表达式进行匹配
    matches = re.findall(date_pattern, date)

    # 输出匹配到的日期
    if matches:
        print("日期:", matches[0])
        return True, matches[0]
    else:
        return False, ''

# 4. -- main --
# 会将Flask程序运行在一个简易服务器上(Flask提供,用于测试)
if __name__ == "__main__":
    logger.info("ocr 服务运行.........")
    server = pywsgi.WSGIServer(('0.0.0.0', 5000), app)
    server.serve_forever()

示例图片

准确率相当高,有问题可以私信!

在浩瀚的代码海洋中,我们一起航行!
架构师资料学习
链接: .

提取码 9kts

Top