提交 f4dfc47a 编写于 作者: K Kentaro Wada

Add labelme2coco.py for instance_segmentation

Close https://github.com/wkentaro/labelme/issues/34
上级 d4d5c809
......@@ -31,6 +31,7 @@ It is written in Python and uses Qt for its graphical interface.
- [x] Video annotation. ([video annotation](examples/video_annotation))
- [x] GUI customization (predefined labels / flags, auto-saving, label validation, etc). ([#144](https://github.com/wkentaro/labelme/pull/144))
- [x] Exporting VOC-like dataset for semantic/instance segmentation. ([semantic segmentation](examples/semantic_segmentation), [instance segmentation](examples/instance_segmentation))
- [x] Exporting COCO-like dataset for instance segmentation. ([instance segmentation](examples/instance_segmentation))
......
......@@ -34,3 +34,13 @@ labelme_draw_label_png data_dataset_voc/SegmentationObjectPNG/2011_000003.png #
```
<img src=".readme/draw_label_png_class.jpg" width="33%" /> <img src=".readme/draw_label_png_object.jpg" width="33%" />
## Convert to COCO-like Dataset
```bash
# It generates:
# - data_dataset_coco/JPEGImages
# - data_dataset_coco/annotations.json
./labelme2coco.py data_annotated data_dataset_coco --labels labels.txt
```
{"info": {"description": null, "url": null, "version": null, "year": 2019, "contributor": null, "date_created": "2019-01-31 23:37:23.484326"}, "licenses": [{"url": null, "id": 0, "name": null}], "images": [{"license": 0, "url": null, "file_name": "JPEGImages/2011_000003.jpg", "height": 338, "width": 500, "date_captured": null, "id": 0}, {"license": 0, "url": null, "file_name": "JPEGImages/2011_000025.jpg", "height": 375, "width": 500, "date_captured": null, "id": 1}, {"license": 0, "url": null, "file_name": "JPEGImages/2011_000006.jpg", "height": 375, "width": 500, "date_captured": null, "id": 2}], "type": "instances", "annotations": [{"segmentation": {"size": [338, 500], "counts": "Zco13\\94_G2Y8<[GJ]8?\\GG[8>dGGT8=jGIn7;PHIj7;THHg7e1J6K5L4N2M3N2M3N2M3N2N2M3N2M>C=B2O1M3M3M3M3\\OgJkK\\5R4lJfKU5Y4c0N2N2N2N2N2N200O100O1O10UNTLPMk3Q3ZLlKL4k3o3^LeK07a3U4dL[K4:Y3[4bM_K^2a4hMZKW2g4j1O010O010O01O10O011N2O0O2O1O0OaJ^KQ5a4nJcKP5]4nJgKo4Z4oJiKP5V4nJlKS5T4kJmKV5d0hJX20UMX5?lJ]2JVMZ58QKU3P5hLSKW3m4iLSKW3n4gLTKY3l4fLUKY3k4fLVKZ3k4dLWK[3j4dLVK\\3k4bLWK^3i4aLXK^3i4`LXK`3j4\\LYKc3h4[LZKe3f4YL[Kg3f4VL]Ki3g5O010O0]OXI\\Mi6`2ZI`Mg6]2[IdMd6\\2\\IcMf6\\2ZIcMh6[2YIeMg6[2YIdMi6[2XIcMj6[2XIcMi6]2XIaMj6^2WIaMj6]2XIaMi6]2YIbMi6\\2YIbMi6[2ZIdMf6Z2]IdMe6Z2k0M3N1N3N2M2O2M3M2O2M5K6POlF6\\9DhF6`9DdF6P:J^kl1"}, "area": 15689.0, "iscrowd": null, "image_id": 0, "category_id": 15}, {"segmentation": {"size": [338, 500], "counts": "ldh35X:6N2O1NM3IT<1SD2N2N2N2N2N2N2N2N2N2M3M3N2dN@SHFMl0P8\\OTHT1j7lNVHV1h7jNXHX1;\\Nb6;TI[18ZNe6:TI]15ZNf69UI_13XNh69UIa11WNi68VIc1OVNj67WIe1LUNm67WIe1JUNn66XIg1HSNP76XIi1FRNP77YIi1EPNR77YIT2f6lM[IT2d6lM\\IT2c6nM\\IS2b6nM^IR2b6nM^IR2a6PN_Io1`6RN`In1`6RN`In1_6SNaIm1^6UNaIk1^6WNbIh1]6[NaIe1^6]NaIc1^6_NaIa1]6`NeI_1Z6bNfI^1Y6cNgI]1X6dNhI\\1W6eNiI[1W6eNjIZ1U6gNkIY1T6hNlIX1T6gNmIY1R6hNnIX1Q6iNPJV1P6jNPJV1o5kNQJU1n5lNRJNEKY67RJOEIX68UJNDIW69UJNDIV6:VJNDGU6<WJMEFT6=UJOHCR6?QJ4M\\OQ6a0mI83VOP6\\2QJcMn5_2RJ`Mm5a2TJ^Ml5b2TJ^Mk5d2UJ[Mj5f2WJYMi5g2XJXMg5j2eJjLZ5V3P11O2O0O1O2O0O101N1O101N1O101\\Oc0N2M4M3L4M4K4M3M3O1O1N3jKiJm2X5nLWKg2j4UM[Kh2h4TM\\Kj2g4QM]Kl2h4nL\\KP3U6N2M3N1O0O11O00010O0000010O00001O01OSOYMnIh2P6_MiId2T6dMeI]2Y6jM`IX2^6UN"}, "area": 17254.0, "iscrowd": null, "image_id": 0, "category_id": 15}, {"segmentation": {"size": [338, 500], "counts": "kni3Z1V92N2N3M2N201OO1000000O10002N2M3Nk0UO<DdhT1"}, "area": 873.0, "iscrowd": null, "image_id": 0, "category_id": 5}, {"segmentation": {"size": [375, 500], "counts": "jim04];5K6J6J6J6J5K6bHMT37gLV1o1lNlM[1P2gNkM`1Q2bNjMd1T2\\NhMk1T2WNgMP2U2RNfMT2W2nMdMY2X2iMcM^2Z2bMcMc2Z2_MaMh2[2ZM`Mm2\\2UM_MQ3_2PM\\MW3`2kL[M\\3a2eL[Ma3b2aLYMf3d2[LWMl3e2VLVMP4g2c2L4L3N3L4L3M4M3L3M2N2N2O1N2N2N2O10000O1000000O10000O1000000O10000O1000000O10000O1000000O10000O1000001NN3L4K4M4L4K4M4M3000O10000O1000000O10000O1000000O10000O1000000O10000O11O0000000000000000000000000000000000000000001O000000000000000000000000000000000000000000001O00000000000000000000000000000000000O1000001O000000000000000000000000000000000000000000000000001O000000000000000000000000000000000000000000000000001O000000000000000000000000000000000000000000000000001O001O00001O001O08I`0_O9HO00001O001O001O000010O01O001O001O00001O010O001O001O00001O001O010O00001O001O001O0010ON2M4L3L6K6J6J6J6J6I8I6J6K5M3M3M3M2N0WJTNg1l1YNUNe1l1[NUNd1l1ZNUNf1k1ZNVNe1j1[NWNd1i1[NYNd1h1[NYNd1g1\\NZNc1f1\\N\\Nb1f1]NZNc1f1]N[Nb1e1]N]NLdMMo37^NGTNE_3c0^NCcN^Oo2n0`N_OROVO^2[1`N[Of3e0[LVOj3h0XLSOl3m0_300J;Ab0^O[Rh0"}, "area": 102701.0, "iscrowd": null, "image_id": 1, "category_id": 6}, {"segmentation": {"size": [375, 500], "counts": "P3Z5^6O000000001O0000001O000000001O000000001O0000001O000004L9H4KO10001O000000001O000000001O0000001N100000001O000000001O0000001O00000O1O2N1O1N2O2N1O1O1O1O2N1O1N2O1O2N1O1_LoH[2R7`MSI_2o6[MVId2k6VM[Ii2f6RM^Im2d6nLaIQ3`6jLeIU3_7O0M4J6J6J6I6K6J6I7J5K6J6J6K5L3L5K5K5L3LeQ_4"}, "area": 15781.0, "iscrowd": null, "image_id": 1, "category_id": 6}, {"segmentation": {"size": [375, 500], "counts": "nce45X;;E;E:F;I7O1O1O001O1O1O1O1O001O1O1O1O001O1O;E<DO10000000000000000000000000000000000000000000000000000000000000000O1000000000000000000000000000000000000000000000000000000000000000Vb0"}, "area": 7256.0, "iscrowd": null, "image_id": 1, "category_id": 7}, {"segmentation": {"size": [375, 500], "counts": "XmQ13b;7J7H5K2O1N2O1N2bGXOl5i0jIAT6a0bII]68YI2e60PI;n6GhHc0W7]O`Hm0^7SOZHW1e7hNVH_1i7`NWHc1g7\\NYHf1f7YNYHj1f7UNZHm1e7RN[HP2e7Q1O1O1O1O2N1O1OeLcH^2\\7bMeH^2Z7cMeH^2Z7bMgH^2Y7aMhH_2W7aMiHa2U7_MlHa2S7`MmH`2R7`MnHa2Q7_MPIa2o6_MRIa2m6`MRIa2m6_MTIa2k6_MVIa2i6_MWIc2g6^MYIa2h6^MYIa2g6_MYIb2f6^M[Ia2e6_M\\I`2d6aM[I_2e6aM\\I^2d6bM]I^2b6bM^I^2b6cM^I\\2b6dM_I[2a6eM_I\\2`6dM_I]2b6cM]IW2i6iMVIm1U7SNjHi1[7WNeHi1[7XNcHh1^7XNbHh1^7XNaHi1_7WNaHi1_7WN`Hj1`7WN_Hh1b7XN]Hi1d7VN[Hk1e7UN[Hk1e7S10O1000001O0O2O0K6D;K60O00100O010OO2N1N3M2O0O2N100011N2O1N2O0O2N2O1N101N2O1N2N101N2O11O0O101O000O2O00001O0N2N3M3M3M3L4M3M4L3L4M3M3M3Mh0WO4M2N3M3M3L4M2N3M3L4M3M2N3Mlnm2"}, "area": 15203.0, "iscrowd": null, "image_id": 2, "category_id": 15}, {"segmentation": {"size": [375, 500], "counts": "l_n1n0h:1O1O1O1O1O1O1O1N2O1O1O1O1O1O1O1O2N1000000O10000O1000000O1000000O101O000O10000O1000000O1N2N2N2M3N2M3N3M1N101O0O101N101O0O101N101O2M2O2N1N3N1N3N2N1L2gGiLP8_3PHbLg7i3J6J8K501O0000001O0000001O0000001OO1O100O1O100O1O002O2M2N3N2M2N3M2O2M2N3N1N3M3M2O2M2N3N1N3M2N3N2M2N3N1N3lNmF_OU9=RG^OP9>WG^Ok8<]G_Oe8=bG^O`8>gG^O[8=lG^OV8>d1K6K4LXiU2"}, "area": 11735.0, "iscrowd": null, "image_id": 2, "category_id": 15}, {"segmentation": {"size": [375, 500], "counts": "oal22c;2M3M4M2M3N3L3M3N3M2O2O0O1O2O0O1O2O0O1O2NN3L3L4M4K4L4M4K4M3N30O1O00100O00100O00100O001O1mNGhF8b7GPI8YO2d7KnH9ZOMe7OmH:ZOFg75jH;[OAh79hH=[O[Oj7=fH>]OTOk7c0cH`0]OnNm7g0aHn0\\7WO`Hj0^7[O]Hh0a7\\OZHg0f7d110000O10000O10000O10000O10000O1000000000000001O00000002N4L3N3L3M4L3M4L3N2M2N3M3M3M3N1M4L3M2M3N2N2N2N2N2N2M4M2N2N2K5I7I7I7I7I[f^1"}, "area": 7597.0, "iscrowd": null, "image_id": 2, "category_id": 15}, {"segmentation": {"size": [375, 500], "counts": "d_f16`;=C7J1N2N2N2N2O1N2N2N6J;F9F:F;E5K100O1O1O1O100O1O1O11O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000001O000000000000O1M3L4M3M3M3L4M3M3L4M3N20000O10000O10000O10000O10000O10000O10000O10000O10000O1000000000000000000000000000000000O100000000000000000000000000000000000000000000000O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O10000000000O100000000O10000000000O100000000O10000000000O10000000000O100000000O10000000000O100000000O10000000000O100000000O10000000000O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O1O11O000000001O000000001O000000001O000000001O0000001O000000001O00000N2M4L3M3M3M3L5L3M3M3M3MWa0"}, "area": 44532.0, "iscrowd": null, "image_id": 2, "category_id": 9}, {"segmentation": {"size": [375, 500], "counts": "Rcb41e;1N2O1O1O1N2O1O1N2O1O1O1N2O1O1N2O1O1O1N2O1O1N2O1O11O001O00001O001O001O00001N1O2N1O2N1N2O2N1O4L7Ibbb0"}, "area": 996.0, "iscrowd": null, "image_id": 2, "category_id": 15}, {"segmentation": {"size": [375, 500], "counts": "fi64^;9H8G9I6M00000000000O100000000000001N1000000000000O1000000000001N100000000000000eGgNW6Z1iIfNW6Z1iIfNW6Z1hIgNX6Y1hIgNX6Y1hIhNW6X1iIhNW6Y1gIhNX6Y1hIgNX6Y1hIgNX6Y1gIiNX6W1hIiNX6W1hIiNX6W1hIiNX6W1gIjNX6W1hIjNW6V1iIjNW6V1hIkNX6U1hIkNX6U1hIkNX6U1hIlNW6U1gIlNY6T1gIlNX6U1hIkNX6U1gImNX6S1hImNX6S1hImNX6S1hImNX6S1gInNY6R1gIoNW6R1iInNW6R1hIoNX6Q1hIoNX6Q1hIoNX6g0THPOd1:W6d0\\HnN[1?Y6b0UJ^Oj5b0WJ^Oi5`0XJAh5>YJCf5<[JBg5<[J@i5?WJ_Ol5?VJ]On5b0SJ[Oo5e0QJXOS6f0`2O1O1N2O1OO0O2N2N2M3N3M2N2N2N2N2M3N3M2N2O11O1O1O100O1O1O1O1O1O1O100O1O1O1O1O1O100O1O1O1O1O1O100O1O1O1O1O1O100O1O1O1O1O1O1O100O1O1O1O1O1O100O1O1O1O1O1O100O1O1O_n<0aQC1O1O1O2N1O101N1O1O1O2N1O1O2N1O1O1O2N100O2N1O1O1O2N1O110O0000010O00010OM3L4K6K4L4K5L`\\o0OfcPO3L3M4L4L2N1O1O1O1O1O1O1O1O1O1O2N1O1O1O1eFQOl7P1mGUOT8l0fGYOZ8h0_G^Oa8c0XGCh8>RGGn8:kFKV9[10000000O100000000O100000000O2O0000000O100000000O10000000000O100000000O100000000O100000000O100000000O100000000O101O00000O1O1O1O1O1N2O1O1O1O1O1O1O1O1N2O1O1O1O1000000001O0000001O000000001O0000001OM5H8H9H8G8Hol7"}, "area": 14001.0, "iscrowd": null, "image_id": 2, "category_id": 18}], "categories": [{"supercategory": null, "id": 0, "name": "_background_"}, {"supercategory": null, "id": 1, "name": "aeroplane"}, {"supercategory": null, "id": 2, "name": "bicycle"}, {"supercategory": null, "id": 3, "name": "bird"}, {"supercategory": null, "id": 4, "name": "boat"}, {"supercategory": null, "id": 5, "name": "bottle"}, {"supercategory": null, "id": 6, "name": "bus"}, {"supercategory": null, "id": 7, "name": "car"}, {"supercategory": null, "id": 8, "name": "cat"}, {"supercategory": null, "id": 9, "name": "chair"}, {"supercategory": null, "id": 10, "name": "cow"}, {"supercategory": null, "id": 11, "name": "diningtable"}, {"supercategory": null, "id": 12, "name": "dog"}, {"supercategory": null, "id": 13, "name": "horse"}, {"supercategory": null, "id": 14, "name": "motorbike"}, {"supercategory": null, "id": 15, "name": "person"}, {"supercategory": null, "id": 16, "name": "potted plant"}, {"supercategory": null, "id": 17, "name": "sheep"}, {"supercategory": null, "id": 18, "name": "sofa"}, {"supercategory": null, "id": 19, "name": "train"}, {"supercategory": null, "id": 20, "name": "tv/monitor"}]}
\ No newline at end of file
#!/usr/bin/env python
import argparse
import datetime
import glob
import json
import os
import os.path as osp
import sys
import numpy as np
import PIL.Image
import labelme
try:
import pycocotools.mask
except ImportError:
print('Please install pycocotools:\n\n pip install pycocotools\n')
sys.exit(1)
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument('input_dir', help='input annotated directory')
parser.add_argument('output_dir', help='output dataset directory')
parser.add_argument('--labels', help='labels file')
args = parser.parse_args()
if osp.exists(args.output_dir):
print('Output directory already exists:', args.output_dir)
sys.exit(1)
os.makedirs(args.output_dir)
os.makedirs(osp.join(args.output_dir, 'JPEGImages'))
print('Creating dataset:', args.output_dir)
now = datetime.datetime.now()
data = dict(
info=dict(
description=None,
url=None,
version=None,
year=now.year,
contributor=None,
date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'),
),
licenses=[dict(
url=None,
id=0,
name=None,
)],
images=[
# license, url, file_name, height, width, date_captured, id
],
type='instances',
annotations=[
# segmentation, area, iscrowd, image_id, bbox, category_id, id
],
categories=[
# supercategory, id, name
],
)
class_name_to_id = {}
for i, line in enumerate(open(args.labels).readlines()):
class_id = i - 1 # starts with -1
class_name = line.strip()
if class_id == -1:
assert class_name == '__ignore__'
continue
elif class_id == 0:
assert class_name == '_background_'
class_name_to_id[class_name] = class_id
data['categories'].append(dict(
supercategory=None,
id=class_id,
name=class_name,
))
out_ann_file = osp.join(args.output_dir, 'annotations.json')
label_files = glob.glob(osp.join(args.input_dir, '*.json'))
for image_id, label_file in enumerate(label_files):
print('Generating dataset from:', label_file)
with open(label_file) as f:
label_data = json.load(f)
base = osp.splitext(osp.basename(label_file))[0]
out_img_file = osp.join(
args.output_dir, 'JPEGImages', base + '.jpg'
)
img_file = osp.join(
osp.dirname(label_file), label_data['imagePath']
)
img = np.asarray(PIL.Image.open(img_file))
PIL.Image.fromarray(img).save(out_img_file)
data['images'].append(dict(
license=0,
url=None,
file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)),
height=img.shape[0],
width=img.shape[1],
date_captured=None,
id=image_id,
))
masks = {}
for shape in label_data['shapes']:
points = shape['points']
label = shape['label']
shape_type = shape.get('shape_type', None)
mask = labelme.utils.shape_to_mask(
img.shape[:2], points, shape_type
)
mask = np.asfortranarray(mask.astype(np.uint8))
if label in masks:
masks[label] = masks[label] | mask
else:
masks[label] = mask
for label, mask in masks.items():
cls_name = label.split('-')[0]
if cls_name not in class_name_to_id:
continue
cls_id = class_name_to_id[cls_name]
segmentation = pycocotools.mask.encode(mask)
segmentation['counts'] = segmentation['counts'].decode()
area = float(pycocotools.mask.area(segmentation))
data['annotations'].append(dict(
segmentation=segmentation,
area=area,
iscrowd=None,
image_id=image_id,
category_id=cls_id,
))
with open(out_ann_file, 'w') as f:
json.dump(data, f)
if __name__ == '__main__':
main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册