Create cityscapes_labels.py
Browse files- cityscapes_labels.py +185 -0
cityscapes_labels.py
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/python
|
2 |
+
|
3 |
+
# SPDX-License-Identifier: Apache-2.0
|
4 |
+
|
5 |
+
#
|
6 |
+
'''
|
7 |
+
This script contains label names, original ids, modified train ids and color maps for the categories in the cityscapes dataset.
|
8 |
+
Used in the duc-inference.ipynb and duc-validation.ipynb
|
9 |
+
'''
|
10 |
+
from collections import namedtuple
|
11 |
+
|
12 |
+
|
13 |
+
#--------------------------------------------------------------------------------
|
14 |
+
# Definitions
|
15 |
+
#--------------------------------------------------------------------------------
|
16 |
+
|
17 |
+
# a label and all meta information
|
18 |
+
Label = namedtuple( 'Label' , [
|
19 |
+
|
20 |
+
'name' , # The identifier of this label, e.g. 'car', 'person', ... .
|
21 |
+
# We use them to uniquely name a class
|
22 |
+
|
23 |
+
'id' , # An integer ID that is associated with this label.
|
24 |
+
# The IDs are used to represent the label in ground truth images
|
25 |
+
# An ID of -1 means that this label does not have an ID and thus
|
26 |
+
# is ignored when creating ground truth images (e.g. license plate).
|
27 |
+
# Do not modify these IDs, since exactly these IDs are expected by the
|
28 |
+
# evaluation server.
|
29 |
+
|
30 |
+
'trainId' , # Feel free to modify these IDs as suitable for your method. Then create
|
31 |
+
# ground truth images with train IDs, using the tools provided in the
|
32 |
+
# 'preparation' folder. However, make sure to validate or submit results
|
33 |
+
# to our evaluation server using the regular IDs above!
|
34 |
+
# For trainIds, multiple labels might have the same ID. Then, these labels
|
35 |
+
# are mapped to the same class in the ground truth images. For the inverse
|
36 |
+
# mapping, we use the label that is defined first in the list below.
|
37 |
+
# For example, mapping all void-type classes to the same ID in training,
|
38 |
+
# might make sense for some approaches.
|
39 |
+
# Max value is 255!
|
40 |
+
|
41 |
+
'category' , # The name of the category that this label belongs to
|
42 |
+
|
43 |
+
'categoryId' , # The ID of this category. Used to create ground truth images
|
44 |
+
# on category level.
|
45 |
+
|
46 |
+
'hasInstances', # Whether this label distinguishes between single instances or not
|
47 |
+
|
48 |
+
'ignoreInEval', # Whether pixels having this class as ground truth label are ignored
|
49 |
+
# during evaluations or not
|
50 |
+
|
51 |
+
'color' , # The color of this label
|
52 |
+
] )
|
53 |
+
|
54 |
+
|
55 |
+
#--------------------------------------------------------------------------------
|
56 |
+
# A list of all labels
|
57 |
+
#--------------------------------------------------------------------------------
|
58 |
+
|
59 |
+
# Please adapt the train IDs as appropriate for you approach.
|
60 |
+
# Note that you might want to ignore labels with ID 255 during training.
|
61 |
+
# Further note that the current train IDs are only a suggestion. You can use whatever you like.
|
62 |
+
# Make sure to provide your results using the original IDs and not the training IDs.
|
63 |
+
# Note that many IDs are ignored in evaluation and thus you never need to predict these!
|
64 |
+
|
65 |
+
labels = [
|
66 |
+
# name id trainId category catId hasInstances ignoreInEval color
|
67 |
+
Label( 'unlabeled' , 0 , 255 , 'void' , 0 , False , True , ( 0, 0, 0) ),
|
68 |
+
Label( 'ego vehicle' , 1 , 255 , 'void' , 0 , False , True , ( 0, 0, 0) ),
|
69 |
+
Label( 'rectification border' , 2 , 255 , 'void' , 0 , False , True , ( 0, 0, 0) ),
|
70 |
+
Label( 'out of roi' , 3 , 255 , 'void' , 0 , False , True , ( 0, 0, 0) ),
|
71 |
+
Label( 'static' , 4 , 255 , 'void' , 0 , False , True , ( 0, 0, 0) ),
|
72 |
+
Label( 'dynamic' , 5 , 255 , 'void' , 0 , False , True , (111, 74, 0) ),
|
73 |
+
Label( 'ground' , 6 , 255 , 'void' , 0 , False , True , ( 81, 0, 81) ),
|
74 |
+
Label( 'road' , 7 , 0 , 'flat' , 1 , False , False , (128, 64,128) ),
|
75 |
+
Label( 'sidewalk' , 8 , 1 , 'flat' , 1 , False , False , (244, 35,232) ),
|
76 |
+
Label( 'parking' , 9 , 255 , 'flat' , 1 , False , True , (250,170,160) ),
|
77 |
+
Label( 'rail track' , 10 , 255 , 'flat' , 1 , False , True , (230,150,140) ),
|
78 |
+
Label( 'building' , 11 , 2 , 'construction' , 2 , False , False , ( 70, 70, 70) ),
|
79 |
+
Label( 'wall' , 12 , 3 , 'construction' , 2 , False , False , (102,102,156) ),
|
80 |
+
Label( 'fence' , 13 , 4 , 'construction' , 2 , False , False , (190,153,153) ),
|
81 |
+
Label( 'guard rail' , 14 , 255 , 'construction' , 2 , False , True , (180,165,180) ),
|
82 |
+
Label( 'bridge' , 15 , 255 , 'construction' , 2 , False , True , (150,100,100) ),
|
83 |
+
Label( 'tunnel' , 16 , 255 , 'construction' , 2 , False , True , (150,120, 90) ),
|
84 |
+
Label( 'pole' , 17 , 5 , 'object' , 3 , False , False , (153,153,153) ),
|
85 |
+
Label( 'polegroup' , 18 , 255 , 'object' , 3 , False , True , (153,153,153) ),
|
86 |
+
Label( 'traffic light' , 19 , 6 , 'object' , 3 , False , False , (250,170, 30) ),
|
87 |
+
Label( 'traffic sign' , 20 , 7 , 'object' , 3 , False , False , (220,220, 0) ),
|
88 |
+
Label( 'vegetation' , 21 , 8 , 'nature' , 4 , False , False , (107,142, 35) ),
|
89 |
+
Label( 'terrain' , 22 , 9 , 'nature' , 4 , False , False , (152,251,152) ),
|
90 |
+
Label( 'sky' , 23 , 10 , 'sky' , 5 , False , False , ( 70,130,180) ),
|
91 |
+
Label( 'person' , 24 , 11 , 'human' , 6 , True , False , (220, 20, 60) ),
|
92 |
+
Label( 'rider' , 25 , 12 , 'human' , 6 , True , False , (255, 0, 0) ),
|
93 |
+
Label( 'car' , 26 , 13 , 'vehicle' , 7 , True , False , ( 0, 0,142) ),
|
94 |
+
Label( 'truck' , 27 , 14 , 'vehicle' , 7 , True , False , ( 0, 0, 70) ),
|
95 |
+
Label( 'bus' , 28 , 15 , 'vehicle' , 7 , True , False , ( 0, 60,100) ),
|
96 |
+
Label( 'caravan' , 29 , 255 , 'vehicle' , 7 , True , True , ( 0, 0, 90) ),
|
97 |
+
Label( 'trailer' , 30 , 255 , 'vehicle' , 7 , True , True , ( 0, 0,110) ),
|
98 |
+
Label( 'train' , 31 , 16 , 'vehicle' , 7 , True , False , ( 0, 80,100) ),
|
99 |
+
Label( 'motorcycle' , 32 , 17 , 'vehicle' , 7 , True , False , ( 0, 0,230) ),
|
100 |
+
Label( 'bicycle' , 33 , 18 , 'vehicle' , 7 , True , False , (119, 11, 32) ),
|
101 |
+
Label( 'license plate' , -1 , -1 , 'vehicle' , 7 , False , True , ( 0, 0,142) ),
|
102 |
+
]
|
103 |
+
|
104 |
+
|
105 |
+
#--------------------------------------------------------------------------------
|
106 |
+
# Create dictionaries for a fast lookup
|
107 |
+
#--------------------------------------------------------------------------------
|
108 |
+
|
109 |
+
# Please refer to the main method below for example usages!
|
110 |
+
|
111 |
+
# name to label object
|
112 |
+
name2label = { label.name : label for label in labels }
|
113 |
+
# id to label object
|
114 |
+
id2label = { label.id : label for label in labels }
|
115 |
+
# trainId to label object
|
116 |
+
trainId2label = { label.trainId : label for label in reversed(labels) }
|
117 |
+
# category to list of label objects
|
118 |
+
category2labels = {}
|
119 |
+
for label in labels:
|
120 |
+
category = label.category
|
121 |
+
if category in category2labels:
|
122 |
+
category2labels[category].append(label)
|
123 |
+
else:
|
124 |
+
category2labels[category] = [label]
|
125 |
+
|
126 |
+
#--------------------------------------------------------------------------------
|
127 |
+
# Assure single instance name
|
128 |
+
#--------------------------------------------------------------------------------
|
129 |
+
|
130 |
+
# returns the label name that describes a single instance (if possible)
|
131 |
+
# e.g. input | output
|
132 |
+
# ----------------------
|
133 |
+
# car | car
|
134 |
+
# cargroup | car
|
135 |
+
# foo | None
|
136 |
+
# foogroup | None
|
137 |
+
# skygroup | None
|
138 |
+
def assureSingleInstanceName( name ):
|
139 |
+
# if the name is known, it is not a group
|
140 |
+
if name in name2label:
|
141 |
+
return name
|
142 |
+
# test if the name actually denotes a group
|
143 |
+
if not name.endswith("group"):
|
144 |
+
return None
|
145 |
+
# remove group
|
146 |
+
name = name[:-len("group")]
|
147 |
+
# test if the new name exists
|
148 |
+
if not name in name2label:
|
149 |
+
return None
|
150 |
+
# test if the new name denotes a label that actually has instances
|
151 |
+
if not name2label[name].hasInstances:
|
152 |
+
return None
|
153 |
+
# all good then
|
154 |
+
return name
|
155 |
+
|
156 |
+
#--------------------------------------------------------------------------------
|
157 |
+
# Main for testing
|
158 |
+
#--------------------------------------------------------------------------------
|
159 |
+
|
160 |
+
# just a dummy main
|
161 |
+
if __name__ == "__main__":
|
162 |
+
# Print all the labels
|
163 |
+
print("List of cityscapes labels:")
|
164 |
+
print("")
|
165 |
+
print(" {:>21} | {:>3} | {:>7} | {:>14} | {:>10} | {:>12} | {:>12}".format( 'name', 'id', 'trainId', 'category', 'categoryId', 'hasInstances', 'ignoreInEval' ))
|
166 |
+
print(" " + ('-' * 98))
|
167 |
+
for label in labels:
|
168 |
+
print(" {:>21} | {:>3} | {:>7} | {:>14} | {:>10} | {:>12} | {:>12}".format( label.name, label.id, label.trainId, label.category, label.categoryId, label.hasInstances, label.ignoreInEval ))
|
169 |
+
print("")
|
170 |
+
|
171 |
+
print("Example usages:")
|
172 |
+
|
173 |
+
# Map from name to label
|
174 |
+
name = 'car'
|
175 |
+
id = name2label[name].id
|
176 |
+
print("ID of label '{name}': {id}".format( name=name, id=id ))
|
177 |
+
|
178 |
+
# Map from ID to label
|
179 |
+
category = id2label[id].category
|
180 |
+
print("Category of label with ID '{id}': {category}".format( id=id, category=category ))
|
181 |
+
|
182 |
+
# Map from trainID to label
|
183 |
+
trainId = 0
|
184 |
+
name = trainId2label[trainId].name
|
185 |
+
print("Name of label with trainID '{id}': {name}".format( id=trainId, name=name ))
|