基于深度学习神经网络YOLOv4目标检测的口罩识别系统

第一步:YOLOv4介绍

YOLOv4是一种目标检测算法,它在精度和速度之间取得了最佳的平衡。它是YOLO(You Only Look Once)系列算法的最新版本,通过将目标检测任务转化为一个回归问题,实现了实时目标检测。YOLOv4采用了一系列的调优手段,使得其在目标检测任务中表现出色。

YOLOv4的框架原理主要包括以下几个方面:

  1. BackBone:YOLOv4使用了CSPDarknet53作为其主干网络,该网络结构具有较强的特征提取能力。
  2. 训练策略:YOLOv4采用了多尺度训练和数据增强等策略来提高模型的泛化能力和检测精度。
  3. 推理策略:YOLOv4使用了多尺度推理和后处理技术来提高检测速度和准确性。
  4. 检测头训练策略:YOLOv4使用了Mosaic数据增强和CIoU损失函数等策略来提高小目标的检测精度。
  5. 检测头推理策略:YOLOv4使用了YOLOv3和YOLOv4的检测头结合策略,提高了模型的检测能力。

总之,YOLOv4是一种高效准确的目标检测算法,具有较好的精度和速度表现。它在目标检测领域具有广泛的应用前景。

标注数据,YOLOv4的训练和测试步骤,各路大神都已经做了很多工作,我就不再写了,这里有几个写的比较好的博客可以参考:

【项目实践】YOLO V4万字原理详细讲解并训练自己的数据集(pytorch完整项目打包下载)-腾讯云开发者社区-腾讯云

YOLOv4 的各种新实现、配置、测试、训练资源汇总

第二步:YOLOv4网络结构

第三步:代码展示

#-------------------------------------#
#       创建YOLO类
#-------------------------------------#
import cv2
import numpy as np
import colorsys
import os
import torch
import torch.nn as nn
from nets.yolo4 import YoloBody
import torch.backends.cudnn as cudnn
from PIL import Image, ImageFont, ImageDraw
from torch.autograd import Variable
from utils.utils import non_max_suppression, bbox_iou, DecodeBox, letterbox_image, yolo_correct_boxes

class YOLO(object):
    _defaults = {
        "model_path": 'model_data/yolov4_maskdetect_weights1.pth',
        "anchors_path": 'model_data/yolo_anchors.txt',
        "classes_path": 'model_data/mask_classes.txt',
        "model_image_size" : (608, 608, 3),
        "confidence": 0.5,
        "cuda": True
    }

    @classmethod
    def get_defaults(cls, n):
        if n in cls._defaults:
            return cls._defaults[n]
        else:
            return "Unrecognized attribute name '" + n + "'"

    #---------------------------------------------------#
    #   初始化YOLO
    #---------------------------------------------------#
    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults)
        self.class_names = self._get_class()
        self.anchors = self._get_anchors()
        self.generate()
    #---------------------------------------------------#
    #   获得所有的分类
    #---------------------------------------------------#
    def _get_class(self):
        classes_path = os.path.expanduser(self.classes_path)
        with open(classes_path) as f:
            class_names = f.readlines()
        class_names = [c.strip() for c in class_names]
        return class_names
    
    #---------------------------------------------------#
    #   获得所有的先验框
    #---------------------------------------------------#
    def _get_anchors(self):
        anchors_path = os.path.expanduser(self.anchors_path)
        with open(anchors_path) as f:
            anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        return np.array(anchors).reshape([-1, 3, 2])[::-1,:,:]

    #---------------------------------------------------#
    #   获得所有的分类
    #---------------------------------------------------#
    def generate(self):
        
        self.net = YoloBody(len(self.anchors[0]), len(self.class_names)).eval()

        # 加快模型训练的效率
        print('Loading pretrained weights.')
        
        model_dict = self.net.state_dict()
        pretrained_dict = torch.load(self.model_path)
        pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) ==  np.shape(v)}
        model_dict.update(pretrained_dict)
        self.net.load_state_dict(model_dict)
        
        if self.cuda:
            os.environ["CUDA_VISIBLE_DEVICES"] = '0'
            self.net = nn.DataParallel(self.net)
            self.net = self.net.cuda()
    
        print('Finish loading!')

        self.yolo_decodes = []
        for i in range(3):
            self.yolo_decodes.append(DecodeBox(self.anchors[i], len(self.class_names),  (self.model_image_size[1], self.model_image_size[0])))


        print('{} model, anchors, and classes loaded.'.format(self.model_path))
        # 画框设置不同的颜色
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))

    #---------------------------------------------------#
    #   检测图片
    #---------------------------------------------------#
    def detect_image(self, image):
        image_shape = np.array(np.shape(image)[0:2])

        crop_img = np.array(letterbox_image(image, (self.model_image_size[0],self.model_image_size[1])))
        photo = np.array(crop_img,dtype = np.float32)
        photo /= 255.0
        photo = np.transpose(photo, (2, 0, 1))
        photo = photo.astype(np.float32)
        images = []
        images.append(photo)
        images = np.asarray(images)

        with torch.no_grad():
            images = torch.from_numpy(images)
            if self.cuda:
                images = images.cuda()
            outputs = self.net(images)
            
        output_list = []
        for i in range(3):
            output_list.append(self.yolo_decodes[i](outputs[i]))
        output = torch.cat(output_list, 1)
        batch_detections = non_max_suppression(output, len(self.class_names),
                                                conf_thres=self.confidence,
                                                nms_thres=0.3)
        try:
            batch_detections = batch_detections[0].cpu().numpy()
        except:
            return image
            
        top_index = batch_detections[:,4]*batch_detections[:,5] > self.confidence
        top_conf = batch_detections[top_index,4]*batch_detections[top_index,5]
        top_label = np.array(batch_detections[top_index,-1],np.int32)
        top_bboxes = np.array(batch_detections[top_index,:4])
        top_xmin, top_ymin, top_xmax, top_ymax = np.expand_dims(top_bboxes[:,0],-1),np.expand_dims(top_bboxes[:,1],-1),np.expand_dims(top_bboxes[:,2],-1),np.expand_dims(top_bboxes[:,3],-1)

        # 去掉灰条
        boxes = yolo_correct_boxes(top_ymin,top_xmin,top_ymax,top_xmax,np.array([self.model_image_size[0],self.model_image_size[1]]),image_shape)

        font = ImageFont.truetype(font='model_data/simhei.ttf',size=np.floor(3e-2 * np.shape(image)[1] + 0.5).astype('int32'))

        thickness = (np.shape(image)[0] + np.shape(image)[1]) // self.model_image_size[0]

        mask_num = 0
        nomask_num = 0

        with open("test.txt", "w") as f:
            for i, c in enumerate(top_label):
                predicted_class = self.class_names[c]
                score = top_conf[i]

                top, left, bottom, right = boxes[i]
                top = top - 5
                left = left - 5
                bottom = bottom + 5
                right = right + 5

                top = max(0, np.floor(top + 0.5).astype('int32'))
                left = max(0, np.floor(left + 0.5).astype('int32'))
                bottom = min(np.shape(image)[0], np.floor(bottom + 0.5).astype('int32'))
                right = min(np.shape(image)[1], np.floor(right + 0.5).astype('int32'))

                # 画框框
                label = '{}: {:.2f}'.format(predicted_class, score)
                draw = ImageDraw.Draw(image)
                label_size = draw.textsize(label, font)
                label = label.encode('utf-8')
                f.write(str(label))
                f.write('\n')
                f.write("top: " + str(top) + " left: " + str(left) + " bottom: " + str(bottom) + " right: " + str(right))
                f.write('\n')
                print(label)
                print("top: " + str(top) + " left: " + str(left) + " bottom: " + str(bottom) + " right: " + str(right))

                if top - label_size[1] >= 0:
                    text_origin = np.array([left, top - label_size[1]])
                else:
                    text_origin = np.array([left, top + 1])

                for i in range(thickness):
                    draw.rectangle(
                        [left + i, top + i, right - i, bottom - i],
                        outline=self.colors[self.class_names.index(predicted_class)])
                draw.rectangle(
                    [tuple(text_origin), tuple(text_origin + label_size)],
                    fill=self.colors[self.class_names.index(predicted_class)])
                draw.text(text_origin, str(label,'UTF-8'), fill=(0, 0, 0), font=font)
                if str(label)[2:8]=='nomask':
                    nomask_num += 1
                else:
                    mask_num += 1
                del draw
        return image, nomask_num, mask_num

第四步:运行

运行界面:

识别效果:

第五步:整个工程的内容

代码的下载路径(新窗口打开链接)基于深度学习神经网络YOLOv4目标检测的口罩识别系统

有问题可以私信或者留言,有问必答

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于YOLOv5的口罩识别系统是一个使用YOLOv5模型进行口罩检测和分类的系统。该系统可以识别出人脸上是否戴口罩,并进一步判断戴口罩的质量是否合格。 以下是基于YOLOv5的口罩识别系统的步骤: 1. 数据准备:收集带有口罩和不带口罩的人脸图像,并进行标注。标注可以使用标注工具,将目标的位置和类别标注在图像上,并将标注结果保存在文本文件中。 2. 数据预处理:将标注好的图像和对应的标签文件进行预处理,将它们转换为模型可以接受的格式。可以使用Python的图像处理库,如OpenCV,来读取图像并进行预处理操作,如缩放、归一化等。 3. 模型训练:使用YOLOv5模型对准备好的数据进行训练。可以使用已经训练好的权重文件作为初始权重,然后通过迭代训练来优化模型。训练过程中,可以使用训练集和验证集来监控模型的性能,并根据需要进行调整。 4. 模型评估:使用测试集对训练好的模型进行评估,计算模型的准确率、召回率等指标,以评估模型的性能。 5. 模型部署:将训练好的模型部署到实际应用中。可以使用Python的深度学习框架,如PyTorch或TensorFlow,加载模型并进行推理,即输入一张人脸图像,输出是否戴口罩以及戴口罩的质量。 6. 系统优化:根据实际应用需求,对口罩识别系统进行优化。可以通过调整模型参数、增加训练数据、调整阈值等方式来提高系统的性能和准确率。 以下是一个基于YOLOv5的口罩识别系统的示例代码: ```python import torch from PIL import Image # 加载训练好的模型 model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # 加载测试图像 image = Image.open('test.jpg') # 进行口罩检测 results = model(image) # 打印检测结果 results.print() # 可视化检测结果 results.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值