python口罩识别_口罩检测识别率惊人,这个Python项目开源了

本文介绍了AIZOOTech的FaceMaskDetection项目,这是一个使用TensorFlow进行口罩检测的开源项目。该项目支持多种深度学习框架,提供近8000张人脸口罩数据,模型结构小巧,检测准确率高。通过代码示例展示了如何运行程序,包括对图片、视频和实时摄像头的口罩检测。
摘要由CSDN通过智能技术生成

184860952_2_20200308045542925首先感谢 AIZOOTech 的开源项目 —— FaceMaskDetection😀,以下为该项目的 GitHub 地址:https://github.com/AIZOOTech/FaceMaskDetection184860952_3_2020030804554350测试环境我们采用:Windows 系统;

软件:PyCharm;

使用模型:TensorFlow。先看一下效果:184860952_4_2020030804554381检测出帅气的胡歌没有带口罩。红色框框是圈出人脸部分,上方的字体:NoMask ,准确率 1 (即有 100% 把握认为没带口罩)。如果在多人的情况下,能检测出来吗?如下图所示。184860952_5_20200308045543191不错不错,这个模型能同时检测多人的,并且准确高。有人带口罩,有人没带口罩,能检测出来吗?184860952_6_20200308045543284哇,这个模型很棒。检测出带口罩大叔,和两个没带口罩的小伙子。大家可以先在网页体验一下:https://aizoo.com/face-mask-detection.html184860952_7_20200308045543378接下来,我们具体分析一下这个项目:支持 5 大主流深度学习框架(PyTorch、TensorFlow、MXNet、Keras 和 Caffe),已经写好接口了;可以根据自身的环境选择合适的框架,比如:TensorFlow;所有模型都在 models 文件夹下。

公开了近 8000 张的人脸口罩数据和模型,数据集来自于 WIDER Face 和 MAFA 数据集, 重新修改了标注并进行了校验(主要是 MAFA 和 WIDER Face 的人脸位置定义不一样,所以进行了修改标注)并将其开源出来。184860952_8_20200308045543566模型结构在本项目中使用了 SSD 类型的架构,为了让模型可以实时的跑在浏览器以及终端设备上,将模型设计的非常小,只有 101.5 万个参数。模型结构在本文附录部分。本模型输入大小为 260x260,主干网络只有 8 个卷积层,加上定位和分类层,一共只有 24 层(每层的通道数目基本都是 32\64\128),所以模型特别小,只有 101.5 万参数。模型对于普通人脸基本都能检测出来,但是对于小人脸,检测效果肯定不如大模型。网页使用了 Tensorflow.js 库,所以模型是完全运行在浏览器里面的。运行速度的快慢,取决于电脑配置的高低。模型在五个卷积层上接出来了定位分类层,其大小和 anchor 设置信息如下表。184860952_9_20200308045543597184860952_10_20200308045543659工程包目录结构分析GitHub 工程包下载:https://github.com/AIZOOTech/FaceMaskDetection下载完 FaceMaskDetection 压缩包后,解压后如下图:184860952_11_20200308045543691184860952_12_20200308045543800如何运行程序?以 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运行结果:184860952_13_20200308045543831如果想运行运行视频: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)184860952_14_20200308045543925测试集 PR 曲线因为 WIDER face 是一个任务比较复杂的数据集,模型又设计的非常小,所以对于人脸的 PR 曲线并不是那么性感。这点可以通过设计大模型来提升对于小人脸的检测效果。184860952_15_20200308045543956再次感谢 AIZOOTech 的开源项目 —— FaceMaskDetection。【end】◆原力计划◆《原力计划【第二季】- 学习力挑战》正式开始!即日起至 3月21日,千万流量支持原创作者!更有专属【勋章】等你来挑战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值