Yolov5训练笔记

   Yolov4刚出来没多久,就迎来了Yolov5的面世,尽管其名称还存在很多争议(它配不配叫yolov5的问题),因为其主要是一些工程方面的优化,没有相应的论文,其性能显著优于yolo之前的版本,也包括yolov4。对于我个人而言,好用就行了!本文详细介绍使用yolov5训练自己的数据集的过程。

安装Yolov5

  1. 将yolov5的代码从github拉下来
git clone https://github.com/ultralytics/yolov5
  1. 安装相应的环境依赖
       通常我们可以使用anaconda等工具创建一个独立的虚拟环境,然后再安装相关的依赖
pip install -U -r requirements.txt

   使用pip安装依赖包的时候,一般可以添加国内源,以加快安装速度,比如使用清华源安装opencv-python:

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

制作自己的数据集

  1. 数据标注
       一般我们会使用labelImg工具来标注我们的训练图像,如果没有用过这个工具,请自行百度,工具界面如下:
    在这里插入图片描述
       一张图像的标签内容如下:
    在这里插入图片描述
       由于labelImg工具标注的训练数据是VOC格式,其每个图像的标签存在一个xml文件中,而yolov5工程使用coco数据集格式训练,我们需要将自己标注的标签文件转换成需要的类型,这里提供两个脚本:

   首先是划分训练/验证集,在data目录下包含存放训练图像的目录images和存放标签文件(xml文件)的目录Annotations,创建ImageSets目录,在images和Annotations的同级目录下运行train_val.py脚本,会生成两个txt文件在ImageSets/Main下。

# train_val.py
import os
import random

trainval_percent = 0.1   #可自行进行调节
train_percent = 1
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
#ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
#fval = open('ImageSets/Main/val.txt', 'w')
 
for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        #ftrainval.write(name)
        if i in train:
            ftest.write(name)
        #else:
            #fval.write(name)
    else:
        ftrain.write(name)
#ftrainval.close()
ftrain.close()
#fval.close()
ftest.close()

   然后是转换成coco的数据格式,在data的同级目录下运行make_label.py脚本,生成label文件,这里需要根据自己的实际检测类别修改代码里面的class列表。

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

sets = ['train', 'test']
classes = ['1','2', '3', '4', '5', '6']  #自己训练的类别
def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)

def convert_annotation(image_id):
    in_file = open('data/Annotations/%s.xml' % (image_id))
    out_file = open('data/labels/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
for image_set in sets:
    if not os.path.exists('data/labels/'):
        os.makedirs('data/labels/')
    image_ids = open('data/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('data/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write('data/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

   正确的label文件应该长的下面的样子:
在这里插入图片描述

训练模型

   首先,模型参数配置方面,作者提供了几种不同大小模型的参数配置
在这里插入图片描述   由于我使用的gpu较差,这里我使用的是YOLOv5s版本(这几个里面最小的模型),其参数配置(models下的yolov5s.ymal文件)如下:

# parameters
nc: 6  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple

# anchors
anchors:
  - [116,90, 156,198, 373,326]  # P5/32
  - [30,61, 62,45, 59,119]  # P4/16
  - [10,13, 16,30, 33,23]  # P3/8
  # - [5,6, 7,9, 12,10]      # P2/4

# YOLOv5 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Focus, [64, 3]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, BottleneckCSP, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 9, BottleneckCSP, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, BottleneckCSP, [512]],
   [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
   [-1, 1, SPP, [1024, [5, 9, 13]]],
  ]

# YOLOv5 head
head:
  [[-1, 3, BottleneckCSP, [1024, False]],  # 9:20

   [-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']], # 11:40
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4:40
   [-1, 3, BottleneckCSP, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3:80
   [-1, 3, BottleneckCSP, [256, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 18 (P3/8-small)

   [-2, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, BottleneckCSP, [512, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 22 (P4/16-medium)

   [-2, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, BottleneckCSP, [1024, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 26 (P5/32-large)

   [[], 1, Detect, [nc, anchors]],  # Detect(P5, P4, P3)
  ]

   几个版本的参数配置只有depth_multiple和width_multiple两个参数不同,代表模型的深度和宽度。这里我们需要修改开头的nc参数,代表需要检测的类别数量。

   其次是修改data目录下的coco.yaml文件,才能正确的加载自己的数据进行训练,其内容如下:

# train and val datasets (image directory or *.txt file with image paths)
train: ../coco/train2017.txt  # 118k images
val: ../coco/val2017.txt  # 5k images
test: ../coco/test-dev2017.txt  # 20k images for submission to https://competitions.codalab.org/competitions/20794

# number of classes
nc: 80

# class names
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
        'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
        'hair drier', 'toothbrush']

   这里我们需要将所有的参数都更改为自己的数据,train、val、test分别为训练,验证,测试集的位置,按照之前的脚本,生成的文件在data目录下,nc为自己的检测类别数量,注意这里没有背景类,names为自己标注时候的类别label。

   最后可以调整一下train.py中的参数

check_git_status()
    parser = argparse.ArgumentParser()
    parser.add_argument('--epochs', type=int, default=200)
    parser.add_argument('--batch-size', type=int, default=16)
    parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='*.cfg path')
    parser.add_argument('--data', type=str, default='data/coco.yaml', help='*.data path')
    parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='train,test sizes')
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    parser.add_argument('--resume', action='store_true', help='resume training from last.pt')
    parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
    parser.add_argument('--notest', action='store_true', help='only test final epoch')
    parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
    parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
    parser.add_argument('--weights', type=str, default='./weights/init.pt', help='initial weights path')
    parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')
    parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--adam', action='store_true', help='use adam optimizer')
    parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%')
    parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')

   根据自己的硬件情况,数据量等适当的调整这些参数,开始训练!
在这里插入图片描述

修改网络

   由于作者已经将代码封装得很完美了,如果我们需要简单的修改一下网络结构,只需要修改models下面的.ymaxl文件就够了,比如我们需要检测更小的目标,想要添加一个检测层,可以对yolov5s.ymal文件修改如下:

# parameters
nc: 5  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple

# anchors
anchors:
  - [116,90, 156,198, 373,326]  # P5/32
  - [30,61, 62,45, 59,119]  # P4/16
  - [10,13, 16,30, 33,23]  # P3/8
  - [5,6, 7,9, 12,10]      # P2/4

# YOLOv5 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Focus, [64, 3]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, BottleneckCSP, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 9, BottleneckCSP, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, BottleneckCSP, [512]],
   [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
   [-1, 1, SPP, [1024, [5, 9, 13]]],
  ]

# YOLOv5 head
head:
  [[-1, 3, BottleneckCSP, [1024, False]],  # 9:20

   [-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']], # 11:40
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4:40
   [-1, 3, BottleneckCSP, [512, False]],  # 13

   [-1, 1, Conv, [512,1,1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],
   [-1,3,BottleneckCSP, [512, False]],


   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']], 
   [[-1, 2], 1, Concat, [1]],  # cat backbone P3:80
   [-1, 3, BottleneckCSP, [256, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 18 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 18], 1, Concat, [1]],
   [-1, 3, BottleneckCSP, [256, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],


   [-2, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, BottleneckCSP, [512, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 22 (P4/16-medium)

   [-2, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, BottleneckCSP, [1024, False]],
   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 26 (P5/32-large)

   [[], 1, Detect, [nc, anchors]],  # Detect(P5, P4, P3)
  ]

模型测试

   官方提供的测试脚本:

$ python detect.py --source ./inference/images/ --weights yolov5s.pt --conf 0.4
相关推荐
<p> <span style="font-size:18px;color:#E53333;"><strong><span style="color:#000000;">课程演示环境:Ubuntu</span><br /> <br /> <span style="color:#000000;">需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:训练自己的数据集》,课程链接https://edu.csdn.net/course/detail/28748</span><br /> <br /> YOLOv4</strong></span><span style="font-size:18px;color:#E53333;"><strong>来了!速度和精度双提升!</strong></span> </p> <p> <span style="font-size:16px;"> </span> </p> <p> <span style="font-size:16px;">与</span><span style="font-size:16px;"> YOLOv3 </span><span style="font-size:16px;">相比,新版本的</span><span style="font-size:16px;"> AP(精度) </span><span style="font-size:16px;">和</span><span style="font-size:16px;"> FPS </span><span style="font-size:16px;">(每秒帧率)分别提高了</span><span style="font-size:16px;"> 10% </span><span style="font-size:16px;">和</span><span style="font-size:16px;"> 12%</span><span style="font-size:16px;">。</span><span></span> </p> <p> <span style="font-size:16px;"> </span> </p> <p> <span style="font-size:16px;">YOLO系列是基于深度学习的端到端实时目标检测方法。本课程将手把手地教大家使用</span><span style="font-size:16px;">labelImg</span><span style="font-size:16px;">标注和使用</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">训练自己的数据集。课程实战分为两个项目:单目标检测(足球目标检测)和多目标检测(足球和梅西同时检测)。</span><span></span> </p> <p> <span style="font-size:16px;"> </span> </p> <p> <span style="font-size:16px;">本课程的</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">使用</span><span style="font-size:16px;">AlexAB/darknet</span><span style="font-size:16px;">,在</span><span style="font-size:16px;">Ubuntu</span><span style="font-size:16px;">系统上做项目演示。包括:安装</span><span style="font-size:16px;">YOLOv4、</span><span style="font-size:16px;">标注自己的数据集、整理自己的数据集、修改配置文件、训练自己的数据集、测试训练出的网络模型、性能统计</span><span style="font-size:16px;">(mAP</span><span style="font-size:16px;">计算和画出</span><span style="font-size:16px;">PR</span><span style="font-size:16px;">曲线</span><span style="font-size:16px;">)</span><span style="font-size:16px;">和先验框聚类分析。还将介绍改善</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标训练性能的技巧。</span><span></span> </p> <p> <span style="font-size:16px;"> </span> </p> <p> <span style="font-size:16px;">除本课程《</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标检测实战:训练自己的数据集》外,本人将推出有关</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标检测的系列课程。请持续关注该系列的其它视频课程,包括:</span><span></span> </p> <p> <span style="font-size:16px;">《</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标检测实战:人脸口罩佩戴识别》</span><br /> <span style="font-size:16px;">《</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标检测实战:中国交通标志识别》</span><br /> <span style="font-size:16px;">《</span><span style="font-size:16px;">YOLOv4</span><span style="font-size:16px;">目标检测:原理与源码解析》</span> </p> <p> <br /> </p> <p> <span style="font-size:16px;"><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/202004260858382698.jpg" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;"><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/202004260858535136.jpg" alt="" /><br /> </span> </p> <p> <span style="font-size:16px;"><img src="https://img-bss.csdn.net/202004260859074920.jpg" alt="" /><br /> </span> </p> <p> <span></span> </p> <p> <span></span> </p>
<p class="MsoNormal"> <span style="font-family:'微软雅黑',sans-serif;">YOLO</span><span style="font-family:'微软雅黑',sans-serif;">系列是基于深度学习的端到端实时目标检测方法。 <span>PyTorch</span>版的<span>YOLOv5</span>轻量而性能高,更加灵活和便利。</span><span style="font-family:微软雅黑, sans-serif;"> </span> </p> <p class="MsoNormal"> <span style="font-family:'微软雅黑',sans-serif;">本课程将手把手地教大家使用<span>labelImg</span>标注和使用<span>YOLOv5</span>训练自己的数据集。课程实战分为两个项目:单目标检测(足球目标检测)和多目标检测(足球和梅西同时检测)。</span><span style="font-family:微软雅黑, sans-serif;"> </span> </p> <p class="MsoNormal"> <span style="font-family:'微软雅黑',sans-serif;">本课程的<span>YOLOv5</span>使用<span>ultralytics/yolov5</span>,在<span style="color:#e03e2d;"><strong><span>Windows</span></strong></span>系统上做项目演示。包括:安装<span>YOLOv5</span>、标注自己的数据集、准备自己的数据集、修改配置文件、训练自己的数据集、测试训练出的网络模型和性能统计。</span><span style="font-family:微软雅黑, sans-serif;"> </span> </p> <p class="MsoNormal"> <span style="font-family:微软雅黑, sans-serif;">希望学习Ubuntu上演示的同学,请前往 </span><span style="font-family:微软雅黑, sans-serif;">《</span><span style="font-family:微软雅黑, sans-serif;">YOLOv5(PyTorch)</span><span style="font-family:微软雅黑, sans-serif;">实战:训练自己的数据集(Ubuntu)》课程链接:https://edu.csdn.net/course/detail/30793</span><span style="font-family:宋体;"><span style="font-size:14px;"> </span></span> </p> <p style="margin-left:0cm;">   </p> <p style="margin-left:0cm;"> 本人推出了有关YOLOv5目标检测的系列课程。请持续关注该系列的其它视频课程,包括: </p> <p> 《YOLOv5(PyTorch)目标检测实战:训练自己的数据集》 </p> <p> Ubuntu系统 <strong><a href="https://edu.csdn.net/course/detail/30793"><span style="color:#7c79e5;">https://edu.csdn.net/course/detail/30793</span></a></strong> </p> <p> Windows系统 <strong><a href="https://edu.csdn.net/course/detail/30923"><span style="color:#7c79e5;">https://edu.csdn.net/course/detail/30923</span></a></strong> </p> <p> 《YOLOv5(PyTorch)目标检测:原理与源码解析》<strong><a href="https://edu.csdn.net/course/detail/31428"><span style="color:#7c79e5;">https://edu.csdn.net/course/detail/31428</span></a></strong> </p> <p> 《YOLOv5(PyTorch)目标检测实战:Flask Web部署》<strong><a href="https://edu.csdn.net/course/detail/31087"><span style="color:#7c79e5;">https://edu.csdn.net/course/detail/31087</span></a></strong> </p> <p> 《YOLOv5(PyTorch)目标检测实战:TensorRT加速部署》<strong><a href="https://edu.csdn.net/course/detail/32303"><span style="color:#7c79e5;">https://edu.csdn.net/course/detail/32303</span></a></strong> </p> <p> <img src="https://img-bss.csdnimg.cn/202010090636458614.jpg" alt="课程内容" width="880" height="356" /> </p> <p> <img src="https://img-bss.csdnimg.cn/202010090637068681.jpg" alt="技巧" width="880" height="706" /> </p> <p> <img src="https://img-bss.csdnimg.cn/202010090637267536.jpg" alt="功能" width="880" height="913" /> </p>
<span style="color:#E53333;"><span style="color:#000000;"> </span></span> <p style="font-size:16px;"> <span style="color:#3A4151;">课程演示环境:Ubuntu </span> </p> <p style="font-size:16px;"> </p><p> <span><span style="color:#0070C0;">需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:人脸口罩佩戴检测》</span></span> </p> <p> <span><span style="color:#0070C0;">课程链接:https://edu.csdn.net/course/detail/29123</span></span>  </p> <p style="font-size:16px;"> <span style="background-color:#FFFFFF;">当前,人脸口罩佩戴检测是急需的应用,而YOLOv4是最新的强悍的目标检测技术。本课程使用</span><strong><span style="color:#C00000;">YOLOv4实现实时的人脸口罩佩戴检测</span></strong><span style="background-color:#FFFFFF;">。课程提供</span><strong><span style="color:#C00000;">超万张已标注人脸口罩数据集</span></strong><span style="background-color:#FFFFFF;">。训练后的YOLOv4可对真实场景下人脸口罩佩戴进行</span><span style="background-color:#FFFFFF;">高精度地</span><span style="background-color:#FFFFFF;">实时检测。</span> </p> <p style="font-size:16px;"> <span style="background-color:#FFFFFF;"><br /></span> </p> <p style="font-size:16px;"> <span><span style="background-color:#FFFFFF;"><span style="font-size:16px;">本课程会讲述本项目超万张人脸口罩数据集的制作方法,包括使用labelImg标注工具标注以及如何使用Python代码对第三方数据集进行修复和清洗。</span><br /></span></span> </p> <p style="font-size:16px;"> <span><span style="background-color:#FFFFFF;"><br /></span></span> </p> <p style="font-size:16px;"> 本课程的YOLOv4使用AlexyAB/darknet,在Ubuntu系统上做项目演示。具体项目过程包括:安装YOLOv4、训练集和测试集自动划分、修改配置文件、训练网络模型、测试训练出的网络模型、性能统计(mAP计算和画出PR曲线)和先验框聚类分析。  </p> <p style="font-size:16px;"> <br /></p> <p style="font-size:16px;"> <br /></p> <p style="font-size:16px;"> <img src="https://img-bss.csdn.net/202005200601524939.jpg" alt="" /></p> <p style="font-size:16px;"> <strong>YOLOv4人脸口罩佩戴检测效果</strong> </p> <p style="font-size:16px;"> <img src="https://img-bss.csdn.net/202005200603052758.jpg" alt="" /></p> <p style="font-size:16px;"> <br /></p> <span style="color:#000000;"></span>
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页