From a7eb788b8de70dc278ee23d174804feecca0bbaa Mon Sep 17 00:00:00 2001 From: Skwarson96 Date: Wed, 21 Jun 2023 21:52:01 +0200 Subject: [PATCH 1/5] add requirements.txt --- requirements.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6c1215d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +cffi~=1.15.1 +future~=0.18.3 +Pillow~=9.0.1 +pip~=22.0.4 +wheel~=0.37.1 +cryptography~=3.4.8 +numpy~=1.21.6 +setuptools~=59.6.0 +certifi~=2020.6.20 +pycparser~=2.21 \ No newline at end of file From 65d7feaa6f4a13c6e3fd6241b3189e0ea63415b5 Mon Sep 17 00:00:00 2001 From: Skwarson96 Date: Wed, 21 Jun 2023 23:38:29 +0200 Subject: [PATCH 2/5] add draw_rotated_bboxes --- cocoviewer.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/cocoviewer.py b/cocoviewer.py index 470a4be..a7386b6 100644 --- a/cocoviewer.py +++ b/cocoviewer.py @@ -200,6 +200,44 @@ def draw_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size draw.text((tx0, ty0), text, (255, 255, 255), font=font) +def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size): + for i, (c, obj) in enumerate(zip(obj_categories, objects)): + print('obj', obj) + if 'attributes' in obj.keys(): + if obj['attributes']['rotation'] != 0: + + x = int(obj['bbox'][0]) + y = int(obj['bbox'][1]) + box_width = int(obj['bbox'][2]) + box_height = int(obj['bbox'][3]) + rotation = obj['attributes']['rotation'] + + + points = [(int(x), int(y)), + (int(x + box_width), int(y)), + (int(x + box_width), int(y + box_height)), + (int(x), int(y + box_height))] + + center_point = (int(x + box_width / 2), int(y + box_height / 2)) + + angle_rad = rotation * (3.14159 / 180) + center_x, center_y = center_point + rotated_points = [] + import math + for point in points: + translated_x = point[0] - center_x + translated_y = point[1] - center_y + rotated_x = translated_x * math.cos(angle_rad) - translated_y * math.sin(angle_rad) + rotated_y = translated_x * math.sin(angle_rad) + translated_y * math.cos(angle_rad) + final_x = rotated_x + center_x + final_y = rotated_y + center_y + rotated_points.append((final_x, final_y)) + + draw.polygon(rotated_points, outline="red", width=width) + + break + + def draw_masks(draw, objects, obj_categories, ignore, alpha): """Draws a masks over image.""" masks = [obj["segmentation"] for obj in objects] @@ -616,7 +654,8 @@ def compose_image( draw_masks(draw, objects, names_colors, ignore, alpha) # Draw bounding boxes if bboxes_on: - draw_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) + # draw_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) + draw_rotated_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) del draw # Resulting image self.current_composed_image = Image.alpha_composite(img_open, draw_layer) From 3b72fbebb7d34a2bcf776184c21c7a8712c766b8 Mon Sep 17 00:00:00 2001 From: Skwarson96 Date: Thu, 22 Jun 2023 20:47:34 +0200 Subject: [PATCH 3/5] move labels drawing to function --- cocoviewer.py | 78 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/cocoviewer.py b/cocoviewer.py index a7386b6..a59edd4 100644 --- a/cocoviewer.py +++ b/cocoviewer.py @@ -3,6 +3,7 @@ View images with bboxes from the COCO dataset. """ +import math import argparse import colorsys import json @@ -148,6 +149,41 @@ def get_categories(instances: dict) -> dict: return categories +def show_label(label_size, c, b, draw): + text = c[0] + + try: + try: + # Should work for Linux + font = ImageFont.truetype("DejaVuSans.ttf", size=label_size) + except OSError: + # Should work for Windows + font = ImageFont.truetype("Arial.ttf", size=label_size) + except OSError: + # Load default, note no resize option + # TODO: Implement notification message as popup window + font = ImageFont.load_default() + + tw, th = draw.textsize(text, font) + tx0 = b[0] + ty0 = b[1] - th + + # TODO: Looks weird! We need image dims to make it right + tx0 = max(b[0], max(b[0], tx0)) if tx0 < 0 else tx0 + ty0 = max(b[1], max(0, ty0)) if ty0 < 0 else ty0 + + tx1 = tx0 + tw + ty1 = ty0 + th + + # TODO: The same here + if tx1 > b[2]: + tx0 = max(0, tx0 - (tx1 - b[2])) + tx1 = tw if tx0 == 0 else b[2] + + draw.rectangle((tx0, ty0, tx1, ty1), fill=c[-1]) + draw.text((tx0, ty0), text, (255, 255, 255), font=font) + + def draw_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size): """Puts rectangles on the image.""" # Extracting bbox coordinates @@ -166,38 +202,8 @@ def draw_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size draw.rectangle(b, outline=c[-1], width=width) if labels: - text = c[0] + show_label(label_size, c, b, draw) - try: - try: - # Should work for Linux - font = ImageFont.truetype("DejaVuSans.ttf", size=label_size) - except OSError: - # Should work for Windows - font = ImageFont.truetype("Arial.ttf", size=label_size) - except OSError: - # Load default, note no resize option - # TODO: Implement notification message as popup window - font = ImageFont.load_default() - - tw, th = draw.textsize(text, font) - tx0 = b[0] - ty0 = b[1] - th - - # TODO: Looks weird! We need image dims to make it right - tx0 = max(b[0], max(b[0], tx0)) if tx0 < 0 else tx0 - ty0 = max(b[1], max(0, ty0)) if ty0 < 0 else ty0 - - tx1 = tx0 + tw - ty1 = ty0 + th - - # TODO: The same here - if tx1 > b[2]: - tx0 = max(0, tx0 - (tx1 - b[2])) - tx1 = tw if tx0 == 0 else b[2] - - draw.rectangle((tx0, ty0, tx1, ty1), fill=c[-1]) - draw.text((tx0, ty0), text, (255, 255, 255), font=font) def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size): @@ -210,6 +216,8 @@ def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, la y = int(obj['bbox'][1]) box_width = int(obj['bbox'][2]) box_height = int(obj['bbox'][3]) + box = [x, y, x+box_width, y+box_height] + rotation = obj['attributes']['rotation'] @@ -223,7 +231,7 @@ def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, la angle_rad = rotation * (3.14159 / 180) center_x, center_y = center_point rotated_points = [] - import math + for point in points: translated_x = point[0] - center_x translated_y = point[1] - center_y @@ -233,9 +241,11 @@ def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, la final_y = rotated_y + center_y rotated_points.append((final_x, final_y)) - draw.polygon(rotated_points, outline="red", width=width) + draw.polygon(rotated_points, outline=c[-1], width=width) + + if labels: + show_label(label_size, c, box, draw) - break def draw_masks(draw, objects, obj_categories, ignore, alpha): From 6441be95e2f9aa7832090fcdb5529a50c28db952 Mon Sep 17 00:00:00 2001 From: Skwarson96 Date: Thu, 22 Jun 2023 21:49:31 +0200 Subject: [PATCH 4/5] selection rotated or not & small refactor --- cocoviewer.py | 63 ++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/cocoviewer.py b/cocoviewer.py index a59edd4..b2f29b0 100644 --- a/cocoviewer.py +++ b/cocoviewer.py @@ -205,47 +205,39 @@ def draw_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size show_label(label_size, c, b, draw) - def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size): for i, (c, obj) in enumerate(zip(obj_categories, objects)): - print('obj', obj) - if 'attributes' in obj.keys(): - if obj['attributes']['rotation'] != 0: - - x = int(obj['bbox'][0]) - y = int(obj['bbox'][1]) - box_width = int(obj['bbox'][2]) - box_height = int(obj['bbox'][3]) - box = [x, y, x+box_width, y+box_height] - - rotation = obj['attributes']['rotation'] + x = int(obj['bbox'][0]) + y = int(obj['bbox'][1]) + box_width = int(obj['bbox'][2]) + box_height = int(obj['bbox'][3]) + box = [x, y, x+box_width, y+box_height] + rotation = obj['attributes']['rotation'] - points = [(int(x), int(y)), - (int(x + box_width), int(y)), - (int(x + box_width), int(y + box_height)), - (int(x), int(y + box_height))] + points = [(int(x), int(y)), + (int(x + box_width), int(y)), + (int(x + box_width), int(y + box_height)), + (int(x), int(y + box_height))] - center_point = (int(x + box_width / 2), int(y + box_height / 2)) + center_point = (int(x + box_width / 2), int(y + box_height / 2)) - angle_rad = rotation * (3.14159 / 180) - center_x, center_y = center_point - rotated_points = [] + angle_rad = rotation * (3.14159 / 180) + rotated_points = [] - for point in points: - translated_x = point[0] - center_x - translated_y = point[1] - center_y - rotated_x = translated_x * math.cos(angle_rad) - translated_y * math.sin(angle_rad) - rotated_y = translated_x * math.sin(angle_rad) + translated_y * math.cos(angle_rad) - final_x = rotated_x + center_x - final_y = rotated_y + center_y - rotated_points.append((final_x, final_y)) + for point in points: + translated_x = point[0] - center_point[0] + translated_y = point[1] - center_point[1] + rotated_x = translated_x * math.cos(angle_rad) - translated_y * math.sin(angle_rad) + rotated_y = translated_x * math.sin(angle_rad) + translated_y * math.cos(angle_rad) + final_x = rotated_x + center_point[0] + final_y = rotated_y + center_point[1] + rotated_points.append((final_x, final_y)) - draw.polygon(rotated_points, outline=c[-1], width=width) - - if labels: - show_label(label_size, c, box, draw) + draw.polygon(rotated_points, outline=c[-1], width=width) + if labels: + show_label(label_size, c, box, draw) def draw_masks(draw, objects, obj_categories, ignore, alpha): @@ -664,8 +656,11 @@ def compose_image( draw_masks(draw, objects, names_colors, ignore, alpha) # Draw bounding boxes if bboxes_on: - # draw_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) - draw_rotated_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) + if 'attributes' in objects[0].keys(): + if 'rotation' in objects[0]['attributes']: + draw_rotated_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) + else: + draw_bboxes(draw, objects, labels_on, names_colors, ignore, width, label_size) del draw # Resulting image self.current_composed_image = Image.alpha_composite(img_open, draw_layer) From bda62a45c413f6b99be4dee7b98e13b143edda21 Mon Sep 17 00:00:00 2001 From: Skwarson96 Date: Thu, 22 Jun 2023 21:53:50 +0200 Subject: [PATCH 5/5] add ignore to draw rotated bboxes --- cocoviewer.py | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/cocoviewer.py b/cocoviewer.py index b2f29b0..033dd0d 100644 --- a/cocoviewer.py +++ b/cocoviewer.py @@ -207,37 +207,38 @@ def draw_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size def draw_rotated_bboxes(draw, objects, labels, obj_categories, ignore, width, label_size): for i, (c, obj) in enumerate(zip(obj_categories, objects)): - x = int(obj['bbox'][0]) - y = int(obj['bbox'][1]) - box_width = int(obj['bbox'][2]) - box_height = int(obj['bbox'][3]) - box = [x, y, x+box_width, y+box_height] + if i not in ignore: + x = int(obj['bbox'][0]) + y = int(obj['bbox'][1]) + box_width = int(obj['bbox'][2]) + box_height = int(obj['bbox'][3]) + box = [x, y, x+box_width, y+box_height] - rotation = obj['attributes']['rotation'] + rotation = obj['attributes']['rotation'] - points = [(int(x), int(y)), - (int(x + box_width), int(y)), - (int(x + box_width), int(y + box_height)), - (int(x), int(y + box_height))] + points = [(int(x), int(y)), + (int(x + box_width), int(y)), + (int(x + box_width), int(y + box_height)), + (int(x), int(y + box_height))] - center_point = (int(x + box_width / 2), int(y + box_height / 2)) + center_point = (int(x + box_width / 2), int(y + box_height / 2)) - angle_rad = rotation * (3.14159 / 180) - rotated_points = [] + angle_rad = rotation * (3.14159 / 180) + rotated_points = [] - for point in points: - translated_x = point[0] - center_point[0] - translated_y = point[1] - center_point[1] - rotated_x = translated_x * math.cos(angle_rad) - translated_y * math.sin(angle_rad) - rotated_y = translated_x * math.sin(angle_rad) + translated_y * math.cos(angle_rad) - final_x = rotated_x + center_point[0] - final_y = rotated_y + center_point[1] - rotated_points.append((final_x, final_y)) + for point in points: + translated_x = point[0] - center_point[0] + translated_y = point[1] - center_point[1] + rotated_x = translated_x * math.cos(angle_rad) - translated_y * math.sin(angle_rad) + rotated_y = translated_x * math.sin(angle_rad) + translated_y * math.cos(angle_rad) + final_x = rotated_x + center_point[0] + final_y = rotated_y + center_point[1] + rotated_points.append((final_x, final_y)) - draw.polygon(rotated_points, outline=c[-1], width=width) + draw.polygon(rotated_points, outline=c[-1], width=width) - if labels: - show_label(label_size, c, box, draw) + if labels: + show_label(label_size, c, box, draw) def draw_masks(draw, objects, obj_categories, ignore, alpha):