Skip to content

Commit 6b0eb83

Browse files
authored
Merge pull request #118 from bit-bots/feature/labels_with_team_colors
Feature/labels with team colors
2 parents bdecd3c + 759f4f0 commit 6b0eb83

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

Diff for: yoeo/scripts/createYOEOLabelsFromTORSO-21.py

+39-30
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@
88
from tqdm import tqdm
99

1010

11-
# Available classes for YOEO
12-
CLASSES = {
13-
'bb_classes': ['ball', 'goalpost', 'robot'],
14-
'segmentation_classes': ['background', 'lines', 'field'],
15-
'skip_classes': ['obstacle', 'L-Intersection', 'X-Intersection', 'T-Intersection']
16-
}
17-
18-
1911
def range_limited_float_type_0_to_1(arg):
2012
"""Type function for argparse - a float within some predefined bounds
2113
Derived from 'https://stackoverflow.com/questions/55324449/how-to-specify-a-minimum-or-maximum-float-value-with-argparse/55410582#55410582'.
@@ -37,8 +29,16 @@ def range_limited_float_type_0_to_1(arg):
3729
parser.add_argument("--skip-blurred", action="store_true", help="Skip blurred labels")
3830
parser.add_argument("--skip-concealed", action="store_true", help="Skip concealed labels")
3931
parser.add_argument("--skip-classes", nargs="+", default=[], help="These bounding box classes will be skipped")
32+
parser.add_argument("--robots-with-team-colors", action="store_true", help="The robot class will be subdivided into subclasses, one for each team color (currently either 'blue', 'red' or 'unknown').")
4033
args = parser.parse_args()
4134

35+
# Available classes for YOEO
36+
CLASSES = {
37+
'bb_classes': ['ball', 'goalpost', 'robot'] if not args.robots_with_team_colors else ['ball', 'goalpost', 'robot_blue', 'robot_red', 'robot_unknown'],
38+
'segmentation_classes': ['background', 'lines', 'field'],
39+
'skip_classes': ['obstacle', 'L-Intersection', 'X-Intersection', 'T-Intersection'],
40+
}
41+
4242
# Remove skipped classes from CLASSES list
4343
for skip_class in args.skip_classes:
4444
if skip_class in CLASSES['bb_classes']:
@@ -122,33 +122,42 @@ def range_limited_float_type_0_to_1(arg):
122122
annotations = []
123123

124124
for annotation in image_data['annotations']:
125+
# Skip annotations that are not in the image
126+
if not annotation['in_image']:
127+
continue
128+
129+
# Derive the class name of the current annotation
130+
class_name = annotation['type']
131+
if args.robots_with_team_colors and class_name == 'robot':
132+
class_name += f"_{annotation['color']}"
133+
125134
# Skip annotations, if is not a bounding box or should be skipped or is blurred or concealed and user chooses to skip them
126-
if (annotation['type'] in CLASSES['segmentation_classes'] or # Handled by segmentations
127-
annotation['type'] in CLASSES['skip_classes'] or # Skip this annotation class
135+
if (class_name in CLASSES['segmentation_classes'] or # Handled by segmentations
136+
class_name in CLASSES['skip_classes'] or # Skip this annotation class
128137
(args.skip_blurred and annotation.get('blurred', False)) or
129138
(args.skip_concealed and annotation.get('concealed', False))):
130139
continue
131-
elif annotation['type'] in CLASSES['bb_classes']: # Handle bounding boxes
132-
if annotation['in_image']: # If annotation is not in image, do nothing
133-
min_x = min(map(lambda x: x[0], annotation['vector']))
134-
max_x = max(map(lambda x: x[0], annotation['vector']))
135-
min_y = min(map(lambda x: x[1], annotation['vector']))
136-
max_y = max(map(lambda x: x[1], annotation['vector']))
137-
138-
annotation_width = max_x - min_x
139-
annotation_height = max_y - min_y
140-
relative_annotation_width = annotation_width / img_width
141-
relative_annotation_height = annotation_height / img_height
142-
143-
center_x = min_x + (annotation_width / 2)
144-
center_y = min_y + (annotation_height / 2)
145-
relative_center_x = center_x / img_width
146-
relative_center_y = center_y / img_height
147-
148-
classID = CLASSES['bb_classes'].index(annotation['type']) # Derive classID from index in predefined classes
149-
annotations.append(f"{classID} {relative_center_x} {relative_center_y} {relative_annotation_width} {relative_annotation_height}")
140+
elif class_name in CLASSES['bb_classes']: # Handle bounding boxes
141+
min_x = min(map(lambda x: x[0], annotation['vector']))
142+
max_x = max(map(lambda x: x[0], annotation['vector']))
143+
min_y = min(map(lambda x: x[1], annotation['vector']))
144+
max_y = max(map(lambda x: x[1], annotation['vector']))
145+
146+
annotation_width = max_x - min_x
147+
annotation_height = max_y - min_y
148+
relative_annotation_width = annotation_width / img_width
149+
relative_annotation_height = annotation_height / img_height
150+
151+
center_x = min_x + (annotation_width / 2)
152+
center_y = min_y + (annotation_height / 2)
153+
relative_center_x = center_x / img_width
154+
relative_center_y = center_y / img_height
155+
156+
# Derive classID from index in predefined classes
157+
classID = CLASSES['bb_classes'].index(class_name)
158+
annotations.append(f"{classID} {relative_center_x} {relative_center_y} {relative_annotation_width} {relative_annotation_height}")
150159
else:
151-
print(f"The annotation type '{annotation['type']}' is not supported. Image: '{img_name_with_extension}'")
160+
print(f"The annotation type '{class_name}' is not supported. Image: '{img_name_with_extension}'")
152161

153162
# Store bounding box annotations in .txt file
154163
with open(os.path.join(labels_dir, img_name_without_extension + ".txt"), "w") as output:

0 commit comments

Comments
 (0)