口罩检测识别率惊人,这个Python项目开源了
云栖号:https://yqh.aliyun.com
第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!
昨天在 GitHub 上看到一个有趣的开源项目,它能检测我们是否有戴口罩,跑起程序测试后,发现识别率挺高的,也适应不同环境,于是分享给大家。
首先感谢 AIZOOTech 的开源项目 —— FaceMaskDetection😀
测试环境
我们采用:
- Windows 系统;
- 软件:PyCharm;
- 使用模型:TensorFlow。
先看一下效果:
检测出帅气的胡歌没有带口罩。红色框框是圈出人脸部分,上方的字体:NoMask ,准确率 1 (即有 100% 把握认为没带口罩)。
如果在多人的情况下,能检测出来吗?如下图所示。
不错不错,这个模型能同时检测多人的,并且准确高。
有人带口罩,有人没带口罩,能检测出来吗?
哇,这个模型很棒。检测出带口罩大叔,和两个没带口罩的小伙子。
接下来,我们具体分析一下这个项目:
- 支持 5 大主流深度学习框架(PyTorch、TensorFlow、MXNet、Keras 和 Caffe),已经写好接口了;可以根据自身的环境选择合适的框架,比如:TensorFlow;所有模型都在 models 文件夹下。
- 公开了近 8000 张的人脸口罩数据和模型,数据集来自于 WIDER Face 和 MAFA 数据集, 重新修改了标注并进行了校验(主要是 MAFA 和 WIDER Face 的人脸位置定义不一样,所以进行了修改标注)并将其开源出来。
模型结构
在本项目中使用了 SSD 类型的架构,为了让模型可以实时的跑在浏览器以及终端设备上,将模型设计的非常小,只有 101.5 万个参数。模型结构在本文附录部分。
本模型输入大小为 260x260,主干网络只有 8 个卷积层,加上定位和分类层,一共只有 24 层(每层的通道数目基本都是 3264128),所以模型特别小,只有 101.5 万参数。模型对于普通人脸基本都能检测出来,但是对于小人脸,检测效果肯定不如大模型。
网页使用了 Tensorflow.js 库,所以模型是完全运行在浏览器里面的。运行速度的快慢,取决于电脑配置的高低。
模型在五个卷积层上接出来了定位分类层,其大小和 anchor 设置信息如下表。
工程包目录结构分析
下载完 FaceMaskDetection 压缩包后,解压后如下图:
如何运行程序?
以 TensorFlow 模型为例子,代码中 TensorFlow 版本应该是 1.x;
如果是 TensorFlow 版本是 2.x 的朋友,对应函数修改为 tf.compat.v1.xxxx,使函数与 1.x 版本兼容。
如果想运行图片:
python tenforflow_infer.py --img-path /path/to/your/img
比如,img 目录中作者放了一些图片的,选择 demo2.jpg。
python tenforflow_infer.py --img-path img/demo2.jpg
运行结果:
如果想运行运行视频:
python tenforflow_infer.py --img-mode 0 --video-path /path/to/video
/path/to/video 为视频所在的路径+视频名。
如果想实时使用摄像头检测:
python tenforflow_infer.py --img-mode 0 --video-path 0
这里的 0 ,代表在电脑中设备号;0 默认为电脑自带的摄像头。
如果想使用外接摄像头,可以改为 1 (比如外接上一个 USB 摄像头)。
这里看一下 tenforflow_infer.py 代码:
# -*- coding:utf-8 -*- import cv2 import time import argparse import numpy as np from PIL import Image from keras.models import model_from_json from utils.anchor_generator import generate_anchors from utils.anchor_decode import decode_bbox from utils.nms import single_class_non_max_suppression from load_model.tensorflow_loader import load_tf_model, tf_inference #sess, graph = load_tf_model('FaceMaskDetection-master\models\face_mask_detection.pb') sess, graph = load_tf_model('models\face_mask_detection.pb') # anchor configuration feature_map_sizes = [[33, 33], [17, 17], [9, 9], [5, 5], [3, 3]] anchor_sizes = [[0.04, 0.056], [0.08, 0.11], [0.16, 0.22], [0.32, 0.45], [0.64, 0.72]] anchor_ratios = [[1, 0.62, 0.42]] * 5 # generate anchors anchors = generate_anchors(feature_map_sizes, anchor_sizes, anchor_ratios) #用于推断,批大小为1,模型输出形状为[1,N,4],因此将锚点的dim扩展为[1,anchor_num,4] anchors_exp = np.expand_dims(anchors, axis=0) id2class = {0: 'Mask', 1: 'NoMask'} def inference(image, conf_thresh=0.5, iou_thresh=0.4, target_shape=(160, 160), draw_result=True, show_result=True): ''' 检测推理的主要功能 # :param image:3D numpy图片数组 # :param conf_thresh:分类概率的最小阈值。 # :param iou_thresh:网管的IOU门限 # :param target_shape:模型输入大小。 # :param draw_result:是否将边框拖入图像。 # :param show_result:是否显示图像。 ''' # image = np.copy(image) output_info = [] height, width, _ = image.shape image_resized = cv2.resize(image, target_shape) image_np = image_resized / 255.0 # 归一化到0~1 image_exp = np.expand_dims(image_np, axis=0) y_bboxes_output, y_cls_output = tf_inference(sess, graph, image_exp) # remove the batch dimension, for batch is always 1 for inference. y_bboxes = decode_bbox(anchors_exp, y_bboxes_output)[0] y_cls = y_cls_output[0] # 为了加快速度,请执行单类NMS,而不是多类NMS。 bbox_max_scores = np.max(y_cls, axis=1) bbox_max_score_classes = np.argmax(y_cls, axis=1) # keep_idx是nms之后的活动边界框。 keep_idxs = single_class_non_max_suppression(y_bboxes, bbox_max_scores, conf_thresh=conf_thresh,iou_thresh=iou_thresh) for idx in keep_idxs: conf = float(bbox_max_scores[idx]) class_id = bbox_max_score_classes[idx] bbox = y_bboxes[idx] # 裁剪坐标,避免该值超出图像边界。 xmin = max(0, int(bbox[0] * width)) ymin = max(0, int(bbox[1] * height)) xmax = min(int(bbox[2] * width), width) ymax = min(int(bbox[3] * height), height) if draw_result: if class_id == 0: color = (0, 255, 0) else: color = (255, 0, 0) cv2.rectangle(image, (xmin, ymin), (xmax, ymax), color, 2) cv2.putText(image, "%s: %.2f" % (id2class[class_id], conf), (xmin + 2, ymin - 2), cv2.FONT_HERSHEY_SIMPLEX, 1, color) output_info.append([class_id, conf, xmin, ymin, xmax, ymax]) if show_result: Image.fromarray(image).show() return output_info def run_on_video(video_path, output_video_name, conf_thresh): cap = cv2.VideoCapture(video_path) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) fps = cap.get(cv2.CAP_PROP_FPS) fourcc = cv2.VideoWriter_fourcc(*'XVID') #writer = cv2.VideoWriter(output_video_name, fourcc, int(fps), (int(width), int(height))) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) if not cap.isOpened(): raise ValueError("Video open failed.") return status = True idx = 0 while status: start_stamp = time.time() status, img_raw = cap.read() img_raw = cv2.cvtColor(img_raw, cv2.COLOR_BGR2RGB) read_frame_stamp = time.time() if (status): inference(img_raw, conf_thresh, iou_thresh=0.5, target_shape=(260, 260), draw_result=True, show_result=False) cv2.imshow('image', img_raw[:, :, ::-1]) cv2.waitKey(1) inference_stamp = time.time() # writer.write(img_raw) write_frame_stamp = time.time() idx += 1 print("%d of %d" % (idx, total_frames)) print("read_frame:%f, infer time:%f, write time:%f" % (read_frame_stamp - start_stamp, inference_stamp - read_frame_stamp, write_frame_stamp - inference_stamp)) # writer.release() if __name__ == "__main__": parser = argparse.ArgumentParser(description="Face Mask Detection") parser.add_argument('--img-mode', type=int, default=0, help='set 1 to run on image, 0 to run on video.') #这里设置为1:检测图片;还是设置为0:视频文件(实时图像数据)检测 parser.add_argument('--img-path', type=str, help='path to your image.') parser.add_argument('--video-path', type=str, default='0', help='path to your video, `0` means to use camera.') # parser.add_argument('--hdf5', type=str, help='keras hdf5 file') args = parser.parse_args() if args.img_mode: imgPath = args.img_path #img = cv2.imread("imgPath") img = cv2.imread(imgPath) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) inference(img, show_result=True, target_shape=(260, 260)) else: video_path = args.video_path if args.video_path == '0': video_path = 0 run_on_video(video_path, '', conf_thresh=0.5)
测试集 PR 曲线
因为 WIDER face 是一个任务比较复杂的数据集,模型又设计的非常小,所以对于人脸的 PR 曲线并不是那么性感。这点可以通过设计大模型来提升对于小人脸的检测效果。
再次感谢 AIZOOTech 的开源项目 —— FaceMaskDetection。
云栖号:https://yqh.aliyun.com
第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!
原文发布时间:2020-03-08
本文作者:一颗小树x
本文来自:“AI科技大本营公众号”,了解相关信息可以关注“AI科技大本营”
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
第 432 期 Python 周刊
文章,教程和讲座 关于 Mercurial 移植到 Python3 的一些思考 链接: https://gregoryszorc.com/blog/2020/01/13/mercurial's-journey-to-and-reflections-on-python-3/ Mercurial 5.2 于 2019年11月5日 发布。这是 Mercurial 第一个支持 Python3 的版本。这一里程碑是在 Python3.0 于 2018年12月3日 首次发布之后近11年的时间完成的。从逻辑上讲,该文章分为两部分:对 Mercurial 的 Python3 移植工作的一些真实的叙述,对向 Python3 和整个 Python 语言生态系统的过渡,提出的一些见解。 管理 Python 环境 链接: https://www.pluralsight.com/tech-blog/managing-python-environments/ Python 环境的配置很容易成为巨大的负担。我们将逐步介绍一些可用的工具以提高环境(代码)友好性,并准备了一些备受好评的 Python 的配置项。 在 P...
- 下一篇
6 个前端开发必备工具,提高你的生产力
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 网络为我们提供了多种多样的前端工具,我挑选了6个实用的前端工具,能帮助大家提高工作效率。 1.EnjoyCSS 老实说,我做过很多的前端开发,但一直不擅长CSS。 这个简单易上手的工具在很多时候给了我极大的帮助。它既是一个代码生成器,也是一个视觉编辑器。 你可以用它来创建各种网页元素,例如按钮、输入框,同时给它们添加自定CSS3属性。 2.Prettier Playground Prettier是一个代码格式化工具,支持JavaScript, ES2017, JSX, Angular, Vue, Flow, TypeScript等。 它能够解析代码,使用你自己设定的规则来重新打印出格式规范的代码。 这个工具非常流行,并且有一个线上版本。 3.Postman Postman是一种网页调试与发送网页http请求的chrome插件。 我们可以用来很方便的模拟get或者post或者其他方式的请求来调试接口。 我从事开发来,Postman就一直...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果