共计 3306 个字符,预计需要花费 9 分钟才能阅读完成。
背景
疫情曾经继续很久,打算做一个衰弱码色彩辨认和信息提取的利用。本文采纳 opencv 和 PaddleOCR、Flask 来实现
PaddleOCR
PaddleOCR 旨在打造一套丰盛、当先、且实用的 OCR 工具库,助力开发者训练出更好的模型,并利用落地。
OpenCV
OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库,能够运行在 Linux、Windows、Android 和 Mac OS 操作系统上。[1] 它轻量级而且高效——由一系列 C 函数和大量 C++ 类形成,同时提供了 Python、Ruby、MATLAB 等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
Flask
Flask 是一个轻量级的可定制框架,应用 Python 语言编写,较其余同类型框架更为灵便、轻便、平安且容易上手。它能够很好地联合 MVC 模式进行开发,开发人员分工合作,小型团队在短时间内就能够实现功能丰富的中小型网站或 Web 服务的实现。另外,Flask 还有很强的定制性,用户能够依据本人的需要来增加相应的性能,在放弃外围性能简略的同时实现性能的丰盛与扩大,其弱小的插件库能够让用户实现个性化的网站定制,开发出功能强大的网站。
微信二维码辨认
联合传统计算机视觉和深度学习技术,微信扫码引擎解决了一图多码、大图小码、鲁棒解码等业务痛点和技术难点。只需 3 行代码,轻松领有微信的扫码能力。
import cv2
detector = cv2.wechat_qrcode_WeChatQRCode("detect.prototxt", "detect.caffemodel", "sr.prototxt", "sr.caffemodel")
img = cv2.imread("img.jpg")
res, points = detector.detectAndDecode(img)
print(res, points)
从下面的代码中可获取二维码的范畴,接下来次要应用预约好的色彩范畴去生成等值线,判断是否存在
# 检测色彩
def detect_color(image, color):
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # HSV
inRange_hsv = cv2.inRange(hsv, color_dist[color]['Lower'], color_dist[color]['Upper'])
contours = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
if len(contours) > 0 and draw_color_area(image, contours) > 0:
return True
else:
return False
# 标记色彩区域
def draw_color_area(image, contours):
allarea, index = 0, -1
for i in range(len(contours)):
area = cv2.contourArea(contours[i])
allarea = area + allarea
return allarea
文字辨认
文字辨认中次要应用了 paddleocr,目前用的笨办法全副辨认进去当前再去用正则表达式去匹配出适合的文字,次要是关注核酸工夫和是否阴性。为了能离线应用,最好提前下载好模型文件。初始化代码:
ocr = PaddleOCR(rec_model_dir='./ocr/rec/ch/ch_PP-OCRv3_rec_infer',det_model_dir='./ocr/det/ch/ch_PP-OCRv3_det_infer', cls_model_dir='./ocr/cls/ch_ppocr_mobile_v2.0_cls_infer')
文字辨认代码:
def getText(img):
res = ocr.ocr(img, det=True, cls=False)
pattern = re.compile('[0-9]+')
qgtime = '暂无数据'
isYin = ''
for i in res:
#print(i)
match= pattern.findall(i[1][0])
if (i[1][0].find(u"小时")>-1 or i[1][0].find(u"天")>-1) and match:
qgtime=i[1][0]
if (i[1][0].find(u"阴")>-1 or i[1][0].find(u"阳")>-1) and i[1][0].find(u"性")>-1:
isYin=i[1][0]
return qgtime,isYin
上传文件接口
用户要通过上传图片文件来实现辨认操作,这时候就须要应用 flask。上传接口须要简略设置下跨域 (不便调试) 以及路由接口,同时要验证文件后缀名,以保障上传指定的文件。
# 判断文件是否非法
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@app.route('/detect', methods=['POST'], strict_slashes=False)
@cross_origin(supports_credentials=True)
def dataDectect():
#print(datetime.datetime.now())
starttime = datetime.datetime.now()
file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER']) # 拼接成非法文件夹地址
file_dir = app.config['UPLOAD_FOLDER'] # 拼接成非法文件夹地址
if not os.path.exists(file_dir):
os.makedirs(file_dir) # 文件夹不存在就创立
f = request.files['img'] # 从表单的 file 字段获取文件,myfile 为该表单的 name 值
if f and allowed_file(f.filename): # 判断是否是容许上传的文件类型
fname = f.filename
ext = fname.rsplit('.', 1)[1] # 获取文件后缀
unix_time = int(time.time())
new_filename = str(unix_time) + '.' + ext # 批改文件名
filePath = os.path.join(file_dir, new_filename)
#print(datetime.datetime.now())
f.save(filePath) # 保留文件到 upload 目录
#print(datetime.datetime.now())
img = cv2.imread(filePath)
codeName = webchatQrDetect(img)
qrtime,isYin=getText(img)
endtime = datetime.datetime.now()
duringtime = endtime - starttime
os.remove(filePath)
#print(datetime.datetime.now())
#print('the work use', duringtime. microseconds/1000000)
# print('the work end', datetime.datetime.now(), datetime.datetime.now())
return jsonify({"运行工夫":str(round(duringtime. seconds,3))+'s',"msg": "上传胜利",u"核酸工夫": qrtime,u'状态':isYin, u"衰弱码": codeName})
else:
return jsonify({"msg": "上传失败"})
我的项目成果
通过 postman 能够调用接口进行测试