今天优化了下之前的初步识别服务的python代码和html代码。
采用flask + paddleocr+ bootstrap快速搭建OCR识别服务。
代码结构如下:
模板页面代码文件如下:
upload.html :
PandaCodeOCR
PandaCodeOCR
主要python代码文件如下:
myapp.py:
import json
import os
import time
from flask import Flask, render_template, request, jsonify
from paddleocr import PaddleOCR
from PIL import Image, ImageDraw
import numpy as np
# 应用名称,当前py名称,视图函数
app = Flask(__name__)
# 项目文件夹的绝对路径
# BASE_DIR = os.path.dirname(os.path.abspath(__name__))
# 相对路径
BASE_DIR = os.path.dirname(os.path.basename(__name__))
# 上传文件路径
UPLOAD_DIR = os.path.join(os.path.join(BASE_DIR, 'static'), 'upload')
'''
PaddleOCR模型通用识别方法
'''
def rec_model_ocr(img):
# 返回字典结果对象
result_dict = {'result': []}
# paddleocr 目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
# 使用CPU预加载,不用GPU
# 模型路径下必须包含model和params文件,目前开源的v3版本模型 已经是识别率很高的了
# 还要更好的就要自己训练模型了。
ocr = PaddleOCR(det_model_dir='./inference/ch_PP-OCRv3_det_infer/',
rec_model_dir='./inference/ch_PP-OCRv3_rec_infer/',
cls_model_dir='./inference/ch_ppocr_mobile_v2.0_cls_infer/',
use_angle_cls=True, lang="ch", use_gpu=False)
# 识别图片文件
result0 = ocr.ocr(img, cls=True)
result = result0[0]
for index in range(len(result)):
line = result[index]
tmp_dict = {}
points = line[0]
text = line[1][0]
score = line[1][1]
tmp_dict['points'] = points
tmp_dict['text'] = text
tmp_dict['score'] = score
result_dict['result'].append(tmp_dict)
return result_dict
# 转换图片
def convert_image(image, threshold=None):
# 阈值 控制二值化程度,不能超过256,[200, 256]
# 适当调大阈值,可以提高文本识别率,经过测试有效。
if threshold is None:
threshold = 200
print('threshold : ', threshold)
# 首先进行图片灰度处理
image = image.convert("L")
pixels = image.load()
# 在进行二值化
for x in range(image.width):
for y in range(image.height):
if pixels[x, y] > threshold:
pixels[x, y] = 255
else:
pixels[x, y] = 0
return image
@app.route('/')
def upload_file():
return render_template('upload.html')
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
# 每个上传的文件首先会保存在服务器上的临时位置,然后将其实际保存到它的最终位置。
filedata = request.files['upload_file']
upload_filename = filedata.filename
print(upload_filename)
# 保存文件到指定路径
# 目标文件的名称可以是硬编码的,也可以从 request.files[file] 对象的 filename 属性中获取。
# 但是,建议使用 secure_filename() 函数获取它的安全版本
if not os.path.exists(UPLOAD_DIR):
os.makedirs(UPLOAD_DIR)
img_path = os.path.join(UPLOAD_DIR, upload_filename)
filedata.save(img_path)
print('file uploaded successfully')
start = time.time()
print('=======开始OCR识别======')
# 打开图片
img1 = Image.open(img_path)
# 转换图片, 识别图片文本
# print('转换图片,阈值=220时,再转换为ndarray数组, 识别图片文本')
# 转换图片
img2 = convert_image(img1, 220)
# Image图像转换为ndarray数组
img_2 = np.array(img2)
# 识别图片
result_dict = rec_model_ocr(img_2)
# 识别时间
end = time.time()
recognize_time = int((end - start) * 1000)
result_dict["filename"] = upload_filename
result_dict["recognize_time"] = str(recognize_time)
result_dict["error_code"] = "000000"
result_dict["error_msg"] = "识别成功"
# render_template方法:渲染模板
# 参数1: 模板名称 参数n: 传到模板里的数据
# return render_template('result.html', result_dict=result_dict)
# 将数据转换成JSON格式,一般用于ajax异步响应页面,不跳转页面用,等价下面方法
# return json.dumps(result_dict, ensure_ascii=False), {'Content-Type': 'application/json'}
# 将数据转换成JSON格式,一般用于ajax异步响应页面,不跳转页面用
return jsonify(result_dict)
else:
return render_template('upload.html')
if __name__ == '__main__':
# 启动app
app.run(port=8000)
启动flask应用,测试结果如下: