背景
疫情曾经继续很久,打算做一个衰弱码色彩辨认和信息提取的利用。本文采纳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 cv2detector = 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能够调用接口进行测试