最近在训练自己的数据集的时候又出现了一个很笨的错误,首先yolo的标准格式是图片文件夹使用images命名,标签的txt文件夹使用labels命名。
最近跑一些对比实验,由于VOC格式的数据图片存储在JPEGImages文件夹下,这是与yolo的标签格式不同的。
那为什么只是一个文件夹命名格式不同会导致读取不到标签的问题呢?按理来说应该是读取不到图片才对吧,我一开始也是因为这个原因所以完全没怀疑到这个点上。
yolov5和v7读取训练数据使用的是yaml文件。
直接读取的train.txt和val.txt的路径,而train.txt和val.txt中写的是每一张图片的绝对路径,所以读取图片这一块就是不可能出问题的。
那么为什么标签会出问题呢,继续查看utils/datasets.py文件关于获取标签部分的代码。
def img2label_paths(img_paths):
# Define label paths as a function of image paths
# sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings
sa, sb = f'{os.sep}JPEGImages{os.sep}', f'{os.sep}labels{os.sep}' # /images/, /labels/ substrings
return ['txt'.join(x.replace(sa, sb, 1).rsplit(x.split('.')[-1], 1)) for x in img_paths]
可以看到上面我注释掉并附加的一行,源码的意思是将图片的路径中的images替换为labels,就得到了该图片对应的标签的路径了。例如:
我有一个图片名为:
D:\datasets\small-object-detection-datasets\Solar_1200\JPEGImages/000001.tiff
上面img2label_paths函数的作用就是将JPEGImages替换为labels,而源码是将images替换为labels,那自然是找不到图片对应的标签了。
将下面这一行代码
sa, sb = f'{os.sep}JPEGImages{os.sep}', f'{os.sep}labels{os.sep}' # /images/, /labels/ substrings
中的JPEGImages改成你自己的数据集的图片名字就可以了,希望可以帮到和我一样粗心的人吧