口罩检测三之测试与应用

测试图片

导入相关的库

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 argparse
import cv2
import os

配置相关的参数

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--image",  default="example.jpg",  help="输出测试的图像")
parser.add_argument("-f", "--face", type=str, default="face_detector", help="人脸检测器模型目录的路径")
parser.add_argument("-m", "--model", type=str, default="mask_detector.model", help="训练好的口罩检测模型路径")
#可选的概率阈值可以设置为超过50%以上的过滤弱人脸检测
parser.add_argument("-c", "--confidence", type=float, default=0.5, help="过滤弱检测的最小概率")
args = vars(ap.parse_args())

导入人脸模型(这里用别人训练好的模型)

prototxtPath = os.path.sep.join([args["face"], "deploy.prototxt"])
weightsPath = os.path.sep.join([args["face"],  "res10_300x300_ssd_iter_140000.caffemodel"])
net = cv2.dnn.readNet(prototxtPath, weightsPath)

导入前面训练好的口罩检测模型

model = load_model(args["model"])
image = cv2.imread(args["image"])
orig = image.copy()
(h, w) = image.shape[:2]

函数 blobFromImage

blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True)

在进行深度学习或者图片分类时,blobFromImage主要是用来对图片进行预处理。包含两个主要过程:

  • 整体像素值减去平均值(mean)
  • 通过缩放系数(scalefactor)对图片像素值进行缩放(在这里我们将大小调整为300*300)
    image这个就是我们将要输入神经网络进行处理或者分类的图片。
    mean:需要将图片整体减去的平均值,如果我们需要对RGB图片的三个通道分别减去不同的值,那么可以使用3组平均值,如果只使用一组,那么就默认对三个通道减去一样的值。减去平均值(mean):为了消除同一场景下不同光照的图片,对我们最终的分类或者神经网络的影响,我们常常对图片的R、G、B通道的像素求一个平均值,然后将每个像素值减去我们的平均值,这样就可以得到像素之间的相对值,就可以排除光照的影响。
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),  (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()

这里循环检测并提取置信度-confidence,计算特定面的边界框值,并确保该框落在图像的边界内

  • 有几个可疑目标,detections 中的第三个list就存储了多少个list。
  • 最后的每个list中存储的数据,从第二位起分别是:
  • 可疑目标的标签,可疑目标的置信度,最后4个是可疑目标在图片中的位置信息。所以
  • idx = int(detections[0, 0, 1, 1]) 提取第二个可疑目标的标签
  • confidence = detections[0, 0, 1, 2] 提取第二个可疑目标的置信度
  • box = detections[0, 0, 1, 3:7]提取第二个可疑目标的位置信息
for i in range(0, detections.shape[2]):
    # 提取与检测相关的置信度(即概率)
    confidence = detections[0, 0, i, 2]

   # 通过确保置信度大于最小置信度来过滤掉弱检测
    if confidence > args["confidence"]:
        # 计算对象边界框的 (x, y) 坐标
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
        
        # 确保边界框在框架的尺寸范围内
        (startX, startY) = (max(0, startX), max(0, startY))
        (endX, endY) = (min(w - 1, endX), min(h - 1, endY))

        # e提取人脸 ROI,将其从 BGR 转换为 RGB 通道排序,将其大小调整为 224x224,并对其进行预处理
        face = image[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)
        face = np.expand_dims(face, axis=0)

        # 将人脸通过模型来确定人脸是否有口罩
        # 首先,我们根据口罩检测器模型返回的概率确定类标签,并为注释指定相关颜色。
        有口罩的颜色是绿色,没有口罩的颜色是红色。
        (mask, withoutMask) = model.predict(face)[0]

        # 确定我们将用来绘制边界框和文本的类标签和颜色
        label = "Mask" if mask > withoutMask else "No Mask"
        color = (0, 255, 0) if label == "Mask" else (0, 0, 255)

        #在标签中包含概率
        label = "{}: {:.2f}%".format(label, max(mask, withoutMask) * 100)

        # 在输出帧上显示标签和边界框矩形
        cv2.putText(image, label, (startX, startY - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)
        cv2.rectangle(image, (startX, startY), (endX, endY), color, 2)

显示图像

cv2.imshow("Output", image)
cv2.waitKey(0)

效果展示
在这里插入图片描述

参考:Using Facial Landmarks for Overlaying Faces with Masks

猜你喜欢

转载自blog.csdn.net/Peyzhang/article/details/126449437
今日推荐