使用cv.FaceNet和MobileNetV2进行人脸和口罩检测

本例使用上一节训练出来的模型,进行口罩检测。
上一节地址如下,
https://www.jianshu.com/p/0ac62d3750b1

先使用cv.FaceNet Detect出人脸位置,然后截取人脸位置的图像,送入MobileNetV2进行口罩检测。
cvFaceNet的模型文件和protodef文件,可以在如下地址下载,
model, https://gitlab.com/zhuge20100104/cpp_practice/-/blob/master/simple_learn/deep_learning/19_training_neural_network_with_keras2/res10_300x300_ssd_iter_140000.caffemodel?ref_type=heads
protodef,
https://gitlab.com/zhuge20100104/cpp_practice/-/blob/master/simple_learn/deep_learning/19_training_neural_network_with_keras2/deploy.prototxt.txt?ref_type=heads

预测视频可以在此处下载,当然也可以输出摄像头数据,因为本例使用的是docker环境,连接本机摄像头比较麻烦,所以使用视频数据输入流,

https://gitlab.com/zhuge20100104/cpp_practice/-/blob/master/simple_learn/deep_learning/19_training_neural_network_with_keras2/masks.mp4?ref_type=heads

代码如下,
notebook 代码地址如下,
https://gitlab.com/zhuge20100104/cpp_practice/-/blob/master/simple_learn/deep_learning/19_training_neural_network_with_keras2/19.%20Training%20Neural%20Network%20with%20Keras%202.ipynb?ref_type=heads

# 1. 使用上一节训练的模型,进行detector
# 还需要使用OpenCV的一个FaceDetector的模型来检测人脸位置
# 引入库

# import the necessary packages
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
import numpy as np
import imutils
import time
import cv2
import os

def detect_and_predict_mask(frame, faceNet, maskNet):
    # grab the dimensions of the frame and then construct a blob from it
    (h, w) = frame.shape[:2]
    blob = cv2.dnn.blobFromImage(frame, 1.0, (224, 224), (104.0, 177.0, 123.0))
    # pass the blob through the network and obtain the face detections
    faceNet.setInput(blob)
    detections = faceNet.forward()
    print(detections.shape)
    # initialize our list of faces, their corresponding locations,
    # and the list of predictions from our face mask network
    faces = []
    locs = []
    preds = []
    # loop over the detections
    # n个7位的数组,
    # 这7位中第2位 是 confidence
    # 这7位中第 3, 4, 5, 6 位是 startX, startY, endX, endY的比例
    # 根据这些值,查找confidence > 0.5的 人脸的位置
    # 对人脸部分进行切图
    # 然后对切图进行预测
    for i in range(0, detections.shape[2]):
        # extract the confidence (i.e., probability) associated with the detection
        confidence = detections[0, 0, i, 2]
        # filter out weak detections by ensuring the confidence is greater than
        # the minimum confidence
        if confidence > 0.5:
            # compute the (x, y) coordinates of the bounding box for the object
            box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
            (startX, startY, endX, endY) = box.astype('int')
            # ensuring the bounding boxes fall within the dimensions of the frame
            (startX, startY) = (max(0, startX), max(0, startY))
            (endX, endY) = (min(w-1, endX), min(h-1, endY))
            # extract the face ROI, convert it from BGR to RGB channel, 
            # ordering, resize it to 224 * 224, and preprocessing it for face mask detect model
            face = frame[startY: endY, startX: endX]
            # face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
            face = cv2.resize(face, (224, 224))
            face = img_to_array(face)
            face = preprocess_input(face)
            # add the face and bounding boxes to their respective lists
            faces.append(face)
            locs.append((startX, startY, endX, endY))
    # only make predictions if at least one face was detected
    if len(faces) > 0:
        # for faster inferenece, we will make batch predictions on all
        # faces at the same time rather than one-by-one predictions in the above 'for' loop
        faces = np.array(faces, dtype='float32')
        preds = maskNet.predict(faces, batch_size=32)

    # return a 2-tuple of the face locations and their corresponding locations
    return (locs, preds)


# load our searilized face detector model from disk
protoTxtPath = r'./deploy.prototxt.txt'
weightsPath = r'./res10_300x300_ssd_iter_140000.caffemodel'
faceNet = cv2.dnn.readNet(protoTxtPath, weightsPath)

# load the face mask detector model from disk
maskNet = load_model('./mask_detector.keras')

# 启动视频,使用模型开始检测,然后绘制到图片中
import imageio
from datetime import datetime
import matplotlib.pyplot as plt


input_video = 'masks'

video_reader = imageio.get_reader('{}.mp4'.format(input_video))
video_writer = imageio.get_writer('{}_annotated.mp4'.format(input_video), fps=10)

t0 = datetime.now()
n_frames = 0
for frame in video_reader:
    n_frames += 1
    # grab the frame from the video and resize it to have a maximum width of 400 pixels
    frame = imutils.resize(frame, width=400)
    # detect faces in the frame and determine if they are wearing a face mask or not
    (locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet)
    # loop over the detected face locations and their corresponding locations
    for (box, pred) in zip(locs, preds):
        # unpack the bounding box and predictions
        (startX, startY, endX, endY) = box
        (mask, withoutMask) = pred
        # detect the class label and color we'll use to draw the bounding box and text
        label = 'Mask' if mask > withoutMask else 'No Mask'
        color = (0, 255, 0) if label == 'Mask' else (0, 0, 255)
        # include the probability in the label
        label = '{}: {:.2f}%'.format(label, max(mask, withoutMask) * 100)
        cv2.putText(frame, label, (startX, startY+20), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)
        cv2.rectangle(frame, (startX, startY), (endX, endY), color, 2)
    video_writer.append_data(frame)

fps = n_frames/(datetime.now() - t0).total_seconds()
print('Frames processed: {}, speed: {} fps'.format(n_frames, fps))
video_reader.close()
video_writer.close()

效果如下,

image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容