【目标检测算法YOLO学习记录】数据集处理

YOLO全称You Only Look Once,是一个端到端(end-to-end)的目标检测算法,现在已经发展到第三个版本。由于第三个版本已经比较复杂,我们选学习第一个版本。

github上有个同学实现了一个pytorch的版本:https://github.com/xiongzihua/pytorch-YOLO-v1

我基于他的源码学习,学习过程中的代码修改放在:https://git.dev.tencent.com/zzpu/yolov1.git


1 数据集介绍

训练使用的数据集是voc2012,测试使用的数据集是voc2007test,关于数据集的介绍可以看

https://blog.csdn.net/wenxueliu/article/details/80327316

数据集子文件夹存放内容如下:

.
└── VOCdevkit     #根目录
    └── VOC2012   #不同年份的数据集,这里只下载了2012的,还有2007等其它年份的
        ├── Annotations        #存放xml文件,与JPEGImages中的图片一一对应,解释图片的内容等等
        ├── ImageSets          #该目录下存放的都是txt文件,txt文件中每一行包含一个图片的名称,末尾会加上±1表示正负样本
        │   ├── Action
        │   ├── Layout
        │   ├── Main
        │   └── Segmentation
        ├── JPEGImages         #存放源图片
        ├── SegmentationClass  #存放的是图片,分割后的效果,见下文的例子
        └── SegmentationObject #存放的是图片,分割后的效果,见下文的例子

但是作者做了一些处理,将图片标签信息打包进一个txt文件,适应目标检测训练任务需求:

文件内容如下,格式是【图片文件名 物体1信息(左上角X1, 左上 角Y1,右下角X2,右下角Y2,物体类别) ,物体2信息(左上角X1, 左上 角Y1,右下角X2,右下角Y2,物体类别)...】

看下源码中是如何处理的

train_dataset = yoloDataset(root=file_root,list_file=['voc2012.txt'],train=True,transform = [transforms.ToTensor()] )
train_loader = DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=4)


# test_dataset = yoloDataset(root=file_root,list_file='voc07_test.txt',train=False,transform = [transforms.ToTensor()] )
test_dataset = yoloDataset(root=file_root,list_file='voc2007test.txt',train=False,transform = [transforms.ToTensor()] )
test_loader = DataLoader(test_dataset,batch_size=batch_size,shuffle=False,num_workers=4)

载入训练数据集和测试数据集


class yoloDataset(data.Dataset):
    image_size = 448
    def __init__(self,root,list_file,train,transform):
        print('data init')
        self.root=root
        self.train = train
        self.transform=transform
        self.fnames = []            #图片文件名
        self.boxes = []             #图片中物体坐标集合
        self.labels = []            #图片中物体类别集合
        self.mean = (123,117,104)#RGB

        if isinstance(list_file, list):
            # Cat multiple list files together.
            # This is especially useful for voc07/voc12 combination.

            #将voc2007和voc2012两个数据集的标签整合为一个
            tmp_file = '/tmp/listfile.txt'
            os.system('cat %s > %s' % (' '.join(list_file), tmp_file))
            list_file = tmp_file

        with open(list_file) as f:
            lines  = f.readlines()

        for line in lines:
            splited = line.strip().split()
            self.fnames.append(splited[0])  #文件名
            num_boxes = (len(splited) - 1) // 5 #运算符执行地板除法(向下取整除),它会返回整除结果的整数部分
            box=[]
            label=[]
            for i in range(num_boxes):
                x = float(splited[1+5*i])   #左上角
                y = float(splited[2+5*i])
                x2 = float(splited[3+5*i])  #右下角
                y2 = float(splited[4+5*i])
                c = splited[5+5*i]          #分类
                box.append([x,y,x2,y2])

                label.append(int(c)+1)      #图片中物体类别集合
            self.boxes.append(torch.Tensor(box))
            self.labels.append(torch.LongTensor(label))
        #图片中物体数
        self.num_samples = len(self.boxes)

可以看到代码中先将两个数据集的标签整合为一个文件,然后一行一行的读入,用三个列表存储图片文件路径,图片中物体集合和物体类别集合,初始化中并没有做过多处理

        self.fnames = []            #图片文件名
        self.boxes = []             #图片中物体坐标集合
        self.labels = []            #图片中物体类别集合
 

2 YOLO输出适配

YOLO论文中,论文作者训练采用的输入图像分辨率是448x448,S=7,B=2;采用VOC 20类标注物体作为训练数据,C=20。因此输出向量为7*7*(20 + 2*5)=1470维。作者开源出的YOLO代码中,全连接层输出特征向量各维度对应内容如下: 

数据集的图片标签也要适配到这种格式,处理过程主要是在函数encoder中完成的:

  def __getitem__(self,idx):
        fname = self.fnames[idx]
        #读取jpg图片---是BGR格式
        img = cv2.imread(os.path.join(self.root+fname))
        #每张图的标签
        boxes = self.boxes[idx].clone()
        labels = self.labels[idx].clone()

        if self.train:
            #img = self.random_bright(img)
            #左右翻转
            img, boxes = self.random_flip(img, boxes)

            #伸缩变形
            img,boxes = self.randomScale(img,boxes)

            #图片预处理

            #平滑处理
            img = self.randomBlur(img)
            #亮度调节
            img = self.RandomBrightness(img)

            #色度调节
            img = self.RandomHue(img)

            #饱和度调节
            img = self.RandomSaturation(img)

            img,boxes,labels = self.randomShift(img,boxes,labels)
            img,boxes,labels = self.randomCrop(img,boxes,labels)
        # #debug
        # box_show = boxes.numpy().reshape(-1)
        # print(box_show)
        # img_show = self.BGR2RGB(img)
        # pt1=(int(box_show[0]),int(box_show[1])); pt2=(int(box_show[2]),int(box_show[3]))
        # cv2.rectangle(img_show,pt1=pt1,pt2=pt2,color=(0,255,0),thickness=1)
        # plt.figure()
        
        # # cv2.rectangle(img,pt1=(10,10),pt2=(100,100),color=(0,255,0),thickness=1)
        # plt.imshow(img_show)
        # plt.show()
        # #debug
        h,w,_ = img.shape

        #坐标归一化处理
        boxes /= torch.Tensor([w,h,w,h]).expand_as(boxes)

        img = self.BGR2RGB(img) #because pytorch pretrained model use RGB
        img = self.subMean(img,self.mean) #减去均值

        #调整图片尺寸为448*448(因为voc的图片大小不一)
        img = cv2.resize(img,(self.image_size,self.image_size))

        #将图片标签编码到7x7*30的向量
        target = self.encoder(boxes,labels)# 7x7x30
        for t in self.transform:
            img = t(img)

        return img,target
    def __len__(self):
        return self.num_samples

    def encoder(self,boxes,labels):
        '''
        boxes (tensor) [[x1,y1,x2,y2],[]]
        labels (tensor) [...]
        return 7x7x30
        '''
        grid_num = 14
        target = torch.zeros((grid_num,grid_num,30))

        cell_size = 1./grid_num


        #右下坐标-左上坐标
                    #x2,y2    # x1,y1
        wh = boxes[:,2:]-boxes[:,:2]

        #物体中心坐标集合
        cxcy = (boxes[:,2:]+boxes[:,:2])/2
        for i in range(cxcy.size()[0]):
            #物体中心坐标
            cxcy_sample = cxcy[i]

            #指示落在那网格,如[0,0]
            ij = (cxcy_sample/cell_size).ceil()-1 #
            # 0 1     2 3  4    5 6     7 8   9
            #[中心坐标,长宽,置信度,中心坐标,长宽,置信度, 20个类别] x 7x7

            target[int(ij[1]),int(ij[0]),4] = 1             #第一个框的置信度

            target[int(ij[1]),int(ij[0]),9] = 1             #第二个框的置信度

            target[int(ij[1]),int(ij[0]),int(labels[i])+9] = 1      #类别

            #xy为归一化后网格的左上坐标---->相对整张图
            xy = ij*cell_size

            #物体中心相对左上的坐标 ---> 坐标x,y代表了预测的bounding box的中心与栅格边界的相对值
            delta_xy = (cxcy_sample -xy)/cell_size


            #(1) 每个小格会对应B个边界框,边界框的宽高范围为全图,表示以该小格为中心寻找物体的边界框位置。
            #(2) 每个边界框对应一个分值,代表该处是否有物体及定位准确度
            #(3) 每个小格会对应C个概率值,找出最大概率对应的类别P(Class|object),并认为小格中包含该物体或者该物体的一部分。


            target[int(ij[1]),int(ij[0]),2:4] = wh[i]   #坐标w,h代表了预测的bounding box的width、height相对于整幅图像width,height的比例
            target[int(ij[1]),int(ij[0]),:2] = delta_xy

            #每一个网格有两个边框
            target[int(ij[1]),int(ij[0]),7:9] = wh[i]           #长宽
            target[int(ij[1]),int(ij[0]),5:7] = delta_xy        #中心坐标偏移
        return target

这里有一个地方需要注意的是,在YOLOv1中一个每个格子两个bounding box,但是但是最终只选择只选择IOU最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体,所以代码中将拟合的两个目标bounding box,都设置为一样,而且置信度都为1(一个格子一个物体,没有其他)。

3 图片的预处理

图片预处理在上面中提到的__getitem__函数中做的,主要做一些平滑,亮度随机调节等,然后是将图片大小都调整为448*448,因为YOLOv1的输入图片尺寸要求为448*448,而数据集中的图片大小是不一的。

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: YOLO是一种可用于目标检测的深度学习模型,其名字源于"you only look once",意思是只需要一次扫描图像就能够识别出其中的目标物体。YOLO打电话数据集就是一种用于训练YOLO模型的数据集,其中包括了大量的电话相关的图像和相关标注信息。 该数据集可以包含各种不同类型的电话,例如固定电话、手持电话、公用电话等等,并且还包含了各种拨号盘、接收器和电话线等细节部分。使用该数据集训练出的YOLO模型可以广泛应用于识别和跟踪电话以及电话相关的场景,例如电话销售、客服服务、通信监管等等,具有广泛的商业和实用价值。 在训练过程中,为了提高模型的识别精度,可以通过自动标注和手工标注相结合的方式对数据集进行处理,对目标物体的位置、大小、姿态等多种信息进行详尽记录。同时,也可以通过数据增强、多尺度融合等技术手段对数据进行优化处理,以提高模型的泛化能力和适应性。 研究YOLO打电话数据集的应用,可以为我们深入了解目标检测算法的原理和应用提供重要的参考,也为我们拓展和扩展其他领域的数据集提供了借鉴和借鉴的思路。 ### 回答2: YOLO(You Only Look Once)是一种基于深度学习目标检测算法,以其快速、准确地检测出图像中的物体而广受好评。而YOLO 打电话数据集是一个研究项目中所使用的一个数据集。该数据集中包含了大量的带有较高难度的电话场景图像,例如电话机、电话线、人物、隔间等。通过YOLO 打电话数据集,可以训练出依赖该算法目标检测模型,使其能够准确地进行电话场景物体的识别和定位。 在YOLO算法中,先将图像分成多个格子,并在每个格子中得到一个预测框,同时在每个预测框中分别对不同类别的物体进行目标检测。因此,在打电话数据集中,每一张图像都需配有对应的标签,标识出图中的目标物体。通过对这些标签进行训练,可以最终得到一种准确、高效的目标检测模型。 总的来说,YOLO 打电话数据集的使用旨在提升算法的精度和效率,使其在识别电话场景下的物体时更加准确和可靠,有更广泛的应用前景,比如智能安防、无人驾驶、智能制造等领域,都可以受益于该算法。 ### 回答3: YOLO打电话数据集是指用于训练YOLO(You Only Look Once)算法的一组数据集,目的是在图像或视频中检测人们是否在使用电话。这个数据集是由许多真实场景图像和视频剪辑组成的,具有多个不同的背景和环境,以展示算法在各种情况下的准确性。 该数据集通常包括许多带有标记的图像,标记信息包括人的位置、方向、大小和是否使用电话等参数。使用这些图像和标记数据,YOLO算法能够对输入的图像或视频进行实时检测,快速地识别图像中的人是否在使用电话。 使用YOLO打电话数据集可以帮助开发者训练和优化算法模型,从而提高算法的准确性、鲁棒性和实时检测能力。这对于一些应用领域如公共安全、流量监控、自动化生产等都有很大的实际意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值