1.概述 转换KITTI label YOLO格式 | Convert KITTI label to YOLO
自己训练yolov3需要用yolov3格式的数据和标签,KITTI 自带的标签是KITTI格式,与yolo使用的格式不同。用kitti数据集训练yolo,需要转化格式。
1.1本文亮点
本文使用fiftyone库将kitt 格式的7481个label转化为yolo格式,只需要几行代码,非常简洁易懂而且不会犯错。
1.2 其他方法:代码逐个读取文件名并计算容易出错
github上有一些逐个文件名读取txt,计算,并写回的代码。或者转化为xml的VOC 格式再用yolo自带的转换代码转为yolo格式txt文件。作为个人理解不同格式的label如何标注是可以的,实际操作上格外繁琐,而且边框的计算过程是否正确,小数点精度取舍等问题很难验证正确与否。
2. 什么是fiftyone, 为什么我们用fiftyone: 因为它牛x
用于构建高质量数据集和计算机视觉模型的开源工具: fiftyone官网 https://voxel51.com/docs/fiftyone/index.html
2.1 fiftyone 牛x:COCO数据集官方使用 FiftyOne
FiftyOne is an open-source tool facilitating visualization and access to COCO data resources and serves as an evaluation tool for model analysis on COCO. (Source:https://cocodataset.org/#home)
3. 代码
3.1.1 FiftyOne下载kitti数据集
import fiftyone as fo
import fiftyone.utils.kitti
#%%
dataset_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723/"
fiftyone.utils.kitti.download_kitti_detection_dataset( dataset_dir , overwrite=True , cleanup=True )
关键代码只有一行即可下载,非常简洁。overwrite代表有zip是否仍然下载,cleanup代表是否删除zip文件。下载过程中可能会要100多gb磁盘空间。
下载完成后,占用12.6gb磁盘。文件路径下有 train和test文件夹,train下有data和label文件夹, 各自有7481个png和label文件。这些是kitti object detection数据集。
fiftyone.utils.kitti.download_kitti_detection_dataset( dataset_dir , overwrite=True , cleanup=True )
文件路径格式应当如下
<dataset_dir>/
data/
<uuid1>.<ext>
<uuid2>.<ext>
...
labels/
<uuid1>.txt
<uuid2>.txt
...
3.1.2 (建议跳过)加载其他方式下载的kitti数据集或者加载kitti格式的其他数据集或kitti格式的自定义数据集
自己下载kitti数据集,例如自己去官网下载,再load加载容易出错,建议还是用3.1.1的办法,以下仅给出粗略的示例供加载KITTI格式的自定义数据集。原版的KITTI数据集下载并加载还是按3.1.1方法吧。
加载数据集官方示例: https://voxel51.com/docs/fiftyone/user_guide/dataset_creation/datasets.html#kittidetectiondataset
加载数据集官方示例python代码
import fiftyone as fo
name = "my-dataset"
dataset_dir = "/path/to/kitti-detection-dataset"
# Create the dataset
dataset = fo.Dataset.from_dir(
dataset_dir=dataset_dir,
dataset_type=fo.types.KITTIDetectionDataset,
name=name,
)
# View summary info about the dataset
print(dataset)
# Print the first few samples in the dataset
print(dataset.head())
3.2 加载下载好的数据集
先打印当前的数据集list,应该是什么都没有,或者有你之前加载好的。
#%%
print(fo.list_datasets())
导入3.1.1下载好的kitti数据集
#%%
name = "my-dataset-kitti0723_1222"
dataset_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723/train/"
# Create the dataset
dataset = fo.Dataset.from_dir(
dataset_dir=dataset_dir,
dataset_type=fo.types.KITTIDetectionDataset,
name=name,
)
查看加载好的数据集 View summary info about the dataset
print(dataset)
打印一些例子 Print the first few samples in the dataset
print(dataset.head())
print("done")
3.3 导出为YOLO格式
先设置好输出路径,然后选择ground_truth输出全部7481张,格式的话选择fo.types.YOLOv4Dataset。 v3和v4格式是一样的。
output_yolo_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723ConvertToYOLO/"
label_field = "ground_truth"
dataset.export(
export_dir=output_yolo_dir,
dataset_type=fo.types.YOLOv4Dataset,
label_field=label_field,
)
完成后,输出文件夹内有一个data文件夹,里面有7481张图和7481个label标注文件,有一个images.txt内有对应的图像路径,还有obj.names分别是9个类的名字。
image.txt内的路径最好更改为绝对路径,用文本编辑器替换即可。用相对路径的话,yolo训练时候读取可能会报错。
obj.names 内是9个类的名字。
附录 全部代码
import fiftyone as fo
import fiftyone.utils.kitti
#%%
dataset_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723/"
#fiftyone.utils.kitti.download_kitti_detection_dataset( dataset_dir , overwrite=True , cleanup=True )
#%%
print(fo.list_datasets())
#%%
#DELETE DATA
#dataset = fo.load_dataset("my-dataset-kitti0723")#my-dataset-kitti0709
#dataset.delete()
#%%
#import kitti dataset
name = "my-dataset-kitti0723_1222"
dataset_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723/train/"
# Create the dataset
dataset = fo.Dataset.from_dir(
dataset_dir=dataset_dir,
dataset_type=fo.types.KITTIDetectionDataset,
name=name,
)
# View summary info about the dataset
print(dataset)
# Print the first few samples in the dataset
print(dataset.head())
print("done")
#%%
print(fo.list_datasets())
#%%
# convert
output_yolo_dir="/home/yz/PycharmProjects/2022/TRUST-E/ErrorResilienceAnalysisYOLOV3/0723ConvertToYOLO/"
#dataset_type=fo.types.YOLOv4Dataset
label_field = "ground_truth"
dataset.export(
export_dir=output_yolo_dir,
dataset_type=fo.types.YOLOv4Dataset,
label_field=label_field,
)
#fiftyone.utils.data.converters.convert_dataset( input_dir=dataset_dir, input_type=fo.types.KITTIDetectionDataset, input_kwargs=None , dataset_importer=None , output_dir=output_yolo_dir, output_type=fo.types.YOLOv4Dataset , output_kwargs=None , dataset_exporter=None , overwrite=False )