VOC数据集是YOLO模型训练的传统标准文件格式,在模型训练前首先需要创建自己的VOC数据集。下载Pascal VOC数据集,然后把官方VOC数据集里面的内容删除,只保留各个文件夹,然后将自己的数据放置在对应的文件夹中,这样确保待训练的数据格式不出错。该文件夹的主要内容如下所示:
└── VOCdevkit #根目录
└── VOC2012 #不同年份的数据集,这里只下载了2012的,还有2007等其它年份的
├── Annotations #存放xml文件,与JPEGImages中的图片一一对应,解释图片的内容等等
├── ImageSets #该目录下存放的都是txt文件,txt文件中每一行包含一个图片的名称,末尾会加上±1表示正负样本
│ ├── Action
│ ├── Layout
│ ├── Main
│ └── Segmentation
├── JPEGImages #存放源图片
├── SegmentationClass #存放的是图片,语义分割相关
└── SegmentationObject #存放的是图片,实例分割相关
(1)准备好自己用来训练模型的图像,将其存放至上述的JPEGImages 文件夹中,统一命名为000001.jpg , 000002.jpg……格式。
在此过程中可能存在将视频分解为图片来作为训练样本的情况,如果训练的原始数据均为图片,直接阅读 ③,通过Python来统一命名图片。
①首先获取视频的帧数,代码如下:
# -*- coding: utf-8 -*-
import cv2
filename = r"C:\Users\Lenovo\Desktop\lettuce_imgdata\videos\G-L-4.avi"
video_cap = cv2.VideoCapture(filename) # 读取视频
#读取视频帧数
frame_count = 0
all_frames = []
while(True):
ret, frame = video_cap.read()
if ret is False:
break
all_frames.append(frame)
frame_count = frame_count + 1
frame_num = len(all_frames)
print(frame_num)
② 得到视频帧数后,将其填入下面代码中(我的为30),运行将视频分解为一帧一帧的图片并保存:
# -*- coding: utf-8 -*-
import cv2
mp4 = cv2.VideoCapture(r"C:\Users\Lenovo\Desktop\lettuce_imgdata\videos\G-R-1.avi") # 读取视频
is_opened = mp4.isOpened() # 判断是否打开
print(is_opened)
fps = mp4.get(cv2.CAP_PROP_FPS) # 获取视频的帧率
print(fps)
widght = mp4.get(cv2.CAP_PROP_FRAME_WIDTH) # 获取视频的宽度
height = mp4.get(cv2.CAP_PROP_FRAME_HEIGHT) # 获取视频的高度
print(str(widght) + "x" + str(height))
i = 0
while is_opened:
if i == 30: ****# 填写上个过程中得到的视频帧数****
break
else:
i += 1
(flag, frame) = mp4.read() # 读取图片
file_name = r"C:\Users\Lenovo\Desktop\lettuce_imgdata\videos\4\lettuce_" + str(i) + ".jpg"
print(file_name)
if flag == True:
cv2.imwrite(file_name, frame, [cv2.IMWRITE_JPEG_QUALITY,100]) # 保存图片
print("Done!")
③ 对所有待训练图片进行文件名统一,代码如下:
# -*- coding: utf-8 -*-
import os
# Function to rename multiple files
def main():
for count, filename in enumerate(os.listdir("C:/Users/Lenovo/Desktop/images")):
dst =str(count) + ".jpg"
src ='C:/Users/Lenovo/Desktop/images/'+ filename
dst ='C:/Users/Lenovo/Desktop/images/lettuce_'+ dst
# rename() function will
# rename all the files
os.rename(src, dst)
# Driver Code
if __name__ == '__main__':
# Calling main() function
main()
(2)下载labelImg软件(提取码:2gba)进行图片上的检测对象标注,并将其生成的.xml文件存储在Annotations文件夹中。
① 解压之后有两个文件,首先记事本打开data文件夹下面的predefined_classes.txt文件,输入需要检测的类别名称,如car,person,dog……每个类别放一行,然后保存。最后运行labelImg.exe文件,如下图所示。
点击左侧工具栏中的Open Dir一直打开至JPEGImages 文件夹,然后确定,后续文件都会从这个文件夹打开;同样点击Change Save Dir直至Annotations文件夹,然后确定,最后会将标注的xml保存至该文件夹中。
Open图片,选择Create RectBox鼠标拖拉选择目标,并选择弹出窗口的类别名称,点击确定,最后点击左侧Save。
在Annotations文件夹中就能保存的xml文件,名称与图像一致。用记事本打开进行检查,发现标注框的width和height均为0:
<annotation>
<folder>JPEGImages</folder>
<filename>lettuce_1.jpg</filename>
<path>D:/YOLO/keras-yolo3-master/VOCdevkit/VOC2012/JPEGImages/lettuce_1.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>0</width> **#图像的width和height均为0**
<height>0</height> **#图像的width和height均为0**
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>lettuce</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>409</xmin>
<ymin>5</ymin>
<xmax>1622</xmax>
<ymax>1014</ymax>
</bndbox>
</object>
</annotation>
这是不正常的,将导致后面模型训练出错,解决该问题的方法为:对JPEGImages文件夹中的所有的图片进行重新写入即可,代码如下:
import cv2
import os
img_path = 'D:\YOLO\keras-yolo3-master\VOCdevkit\VOC2012\JPEGImages'
all_file = os.listdir(img_path)
os.chdir(img_path) # very important
for filename in all_file:
# print(filename)
img=cv2.imread(filename)
cv2.imwrite(filename,img,[int(cv2.IMWRITE_JPEG_QUALITY), 100])
再标注图像后发现xml文件参数正常了,依次标注所有待训练的样本图片,得到完整的JPEGImages和Annotations文件。至此,样本集准备基本结束,后续还需要生成其他训练文件,到下下一节需要处再讲。
下一篇:
Windows10+Darknet+YOLOv3训练自己数据——2.CUDA+cuDNN+Darknet框架配置