# -*- 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