COCO 數據集格式及mmdetection中的轉換方法
COCO格式
CV中的目標檢測任務不同于分類,其標簽的形式稍為復雜,有幾種常用檢測數據集格式,本文將簡要介紹最為常見的COCO數據集的格式。
完整的官方樣例可自行查閱,以下是幾項關鍵的字段:
{"images": [image],"annotations": [annotation],"categories": [category]
}image = {"id": int,"width": int,"height": int,"file_name": str,
}annotation = {"id": int,"image_id": int,"category_id": int,"segmentation": RLE or [polygon],"area": float,"bbox": [x,y,width,height],"iscrowd": 0 or 1,
}categories = [{"id": int,"name": str,"supercategory": str,
}]
以下是一組實例:
dict{'images': list[dict{'id': 0,'file_name': 34020010494_e5cb88e1c4_k.jpg,'height': 1536,'width': 2048}, ...'annotations': list[dict{'image_id': 0,'id': 1,'category_id': 0,'bbox': [135, 115, 676, 850],'area': 574600,'segmentation': [[586.5, ...], []],'is_crowd': 0}, ...'catgories': list[dict{'id': 0,'name': 'balloon'},...]]]
}
首先最外層(json文件讀進來)是一個字典,該字典有三個鍵:'images', 'annotations', 'categories';? 其中'images'是一個列表,長度就是數據集圖像數;? 列表中每個元素又是一個字典,有四個鍵:'id', 'file_name', 'height', 'width',和他們的值? 其中'annotations'也是一個列表,長度就是數據集所有標注(instances)數;? 列表中每個元素又是一個字典,有七個鍵:'image_id', 'id', 'category_id', 'bbox', 'area', 'segmentation', 'is_crowd'? 其中'categories'是一個列表,長度為數據集所含有的類別數;? 列表中每個元素又是一個字典,有兩個鍵:'id', 'name'
mmdetection中的轉換方法
官方例程
mmdetection中提供了幾種訓練自己的數據集的方法,其中之一就是將自己的數據集轉換為COCO格式,進行訓練。
官方給出了balloon數據集的轉換樣例,初次嘗試可以按照此例程學習,這里同時提供balloon數據集下載鏈接。
其他例程
除此之外,筆者想在這里介紹一下另一個非官方的數據集,轉換為COCO格式的例程,供讀者參考。
首先介紹一下這個pig數據集。
與balloon數據集類似,pig數據集只有pig一個類,共700個樣本,原始給出的數據集格式如下:
-
文件路徑
imagesxxx.jpg... labelsxxx.json...
本數據集有兩個文件夾,分別存放images和labels,對應文件名相同,擴展名分別為jpg和json。
-
標注格式
json文件中給出的標注格式如下:
dict{'shape': list[dict{'label': 'pig','boxes': [x1, x2, y1, y2],'points': [[x1, y1], [x2, y2], ..., [xn, yn]]}'imagePath': 'xxx.jpg'] }
json文件最外層是一個字典,該字典有兩個鍵:'shape','imagePath';? 其中'shape'內是一個列表,列表的長度是該張圖片內pig的個數;? 列表內每個元素又是一個字典,有三個鍵:'label','boxes','points';? 其中'imagePath'內則是本標注文件所對應的圖片名。
原本數據集內700個樣本有500個box標注,其他200個是mask標注,經過我的初步處理,已經將沒有box標注的樣本根據mask標注生成了box標注。其中box標注是給出了左上右下兩個對角坐標,而mask標注,也是給出了全部點的坐標。注意此處與COCO數據集給出標注的格式不同,需要做一定的轉換。
轉換為COCO數據集格式的函數如下:
import os
import os.path as osp
import mmcvdef convert_pig_to_coco(img_dir, label_dir, out_file):samples_list = [sample.split('.')[0] for sample in os.listdir(label_dir)]obj_count = 0images = []annotations = []for image_id, sample in enumerate(mmcv.track_iter_progress(samples_list)):prev_dict = mmcv.load(osp.join(label_dir, sample+'.json'))height, width = mmcv.imread(osp.join(img_dir, sample+'.jpg')).shape[: 2]images.append(dict(id = image_id,file_name = sample+'.jpg',height = height,width = width))for pig in prev_dict['shape']:# print(pig['boxes'])x_min, y_min, x_max, y_max = pig['boxes']mask = pig['points']if mask != None:px = [item[0] for item in mask]py = [item[1] for item in mask]poly = [(x + 0.5, y + 0.5) for x, y in zip(px, py)]poly = [p for x in poly for p in x]else:poly = Nonedata_anno = dict(image_id=image_id,id=obj_count,category_id=0,bbox=[x_min, y_min, x_max - x_min, y_max - y_min],area=(x_max - x_min) * (y_max - y_min),segmentation=[poly],iscrowd=0)annotations.append(data_anno)obj_count += 1coco_format_json = dict(images=images,annotations=annotations,categories=[{'id':0, 'name': 'pig'}])mmcv.dump(coco_format_json, out_file)
提供這個額外的例程是為了說明不必拘泥于官方給出的轉換例程框架,要抓住數據集的本質,按照合理的方式將原格式內的數據讀取出來并以COCO數據集的格式存放到一整個json文件中即可。只要完成這項任務,就是成功完成了自己的數據集到COCO格式的數據集的轉換。
另外,如果有與本數據集原格式高度相似的檢測數據集要轉換為COCO格式,也可直接參考本例程的內容。