Test and application of mask detection 3

test picture

Import related libraries

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

Configure related parameters

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())

Import the face model (the model trained by others is used here)

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)

Import the previously trained mask detection model

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

function blobFromImage

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

When performing deep learning or image classification, blobFromImage is mainly used to preprocess images. Contains two main processes:

  • Overall pixel value minus mean (mean)
  • Scale the pixel value of the picture by scaling factor (here we adjust the size to 300*300)
    image This is the picture that we will input into the neural network for processing or classification.
    mean : The average value that needs to be subtracted from the image as a whole. If we need to subtract different values ​​from the three channels of the RGB image, then we can use 3 sets of average values. If only one set is used, then the three channels are used by default. Subtract the same value. Subtract the mean value (mean): In order to eliminate the impact of pictures with different lighting in the same scene on our final classification or neural network, we often calculate an average value for the pixels of the R, G, and B channels of the picture, and then divide each Subtract our average value from each pixel value, so that the relative value between pixels can be obtained, and the influence of illumination can be excluded.
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),  (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()

This loop detects and extracts the confidence -confidence, calculates the bounding box value for a particular face, and ensures that the box falls within the bounds of the image

  • There are several suspicious targets, the third list in the detections stores how many lists.
  • The data stored in each list at the end, from the second digit are:
  • The label of the suspicious target, the confidence of the suspicious target, and the last four are the location information of the suspicious target in the picture. so
  • idx = int(detections[0, 0, 1, 1]) extract the label of the second suspicious object
  • confidence = detections[0, 0, 1, 2] extract the confidence of the second suspicious object
  • box = detections[0, 0, 1, 3:7] extract the location information of the second suspicious target
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)

display image

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

Show results
insert image description here

参考:Using Facial Landmarks for Overlaying Faces with Masks

Guess you like

Origin blog.csdn.net/Peyzhang/article/details/126449437