<jupyter_start><jupyter_text>- Read test COCO image & object boxes & class<jupyter_code>import PIL.Image as pilimg
import numpy as np
from matplotlib.pyplot import imshow
img_path = './COCO_train2014_000000000025.jpg'

# Read image
img = pilimg.open(img_path)
img = np.array(img)

# Show test image
print('size of img:', img.shape)
print('img:', img)
imshow(img)
def load_coco_names(path):
    fp = open(path, "r")
    names = fp.read().split("\n")[:-1]
    return names

label_path = './COCO_train2014_000000000025.txt'
coco_names_path = './coco.names'
coco_names = load_coco_names(coco_names_path)

# Object box list
obj_box_list = []

# Class list
class_list = []

# Read label & get object box and class
try:
    file = open(label_path, mode='r', encoding='utf-8')
    while True:
        line = file.readline().rstrip()
        if not line: break
            
        split_line = np.array(line.split(' '))
        split_line = list(map(float, split_line))
        
        # Object box
        obj_box_list.append(split_line[1:])
        
        # Class index to name
        class_name = coco_names[int(split_line[0])]
        class_list.append(class_name)
finally:
    file.close()
    
obj_box_list = np.array(obj_box_list)
class_list = np.array(class_list)

# Show label
# center_x/center_y/box_w/box_h format, relative scale
print('obj_box_list:', obj_box_list)
print('class_list:', class_list)

data = (img, obj_box_list, class_list)<jupyter_output>obj_box_list: [[0.770336 0.489695 0.335891 0.697559]
 [0.185977 0.901608 0.206297 0.129554]]
class_list: ['giraffe' 'giraffe']<jupyter_text>- Processing for drawing object boxes    1. Convert relative scale to absolute scale of object boxes    2. Convert center_x/center_y/box_w/box_h format to left_top_x/left_top_y/right_bottom_x/right_bottom_y format of object boxes    3. Draw object boxes<jupyter_code>import numpy as np
import cv2
import copy

import imgaug.augmenters as iaa
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn.functional as F
# Convert relative scale to absolute scale of object boxes
class ToAbsoluteScale(object):
    def __init__(self):
        pass
    
    def __call__(self, data):
        img, obj_boxes, obj_classes = data
        h, w, _ = img.shape
        obj_boxes[:, [0, 2]] *= w
        obj_boxes[:, [1, 3]] *= h
        return img, obj_boxes, obj_classes

TRANSFORMS_AbsoluteScale = transforms.Compose([
    ToAbsoluteScale()
])

print('Boxes of relative scale:', data[1])

TRANSFORMS_AbsoluteScale_data = TRANSFORMS_AbsoluteScale(data)
print('Boxes of absolute scale:', TRANSFORMS_AbsoluteScale_data[1])
# Convert center_x/center_y/box_w/box_h format to left_top_x/left_top_y/right_bottom_x/right_bottom_y format of object boxes
def xywh2xyxy_np(x):
    y = np.zeros_like(x)
    y[..., 0] = x[..., 0] - x[..., 2] / 2
    y[..., 1] = x[..., 1] - x[..., 3] / 2
    y[..., 2] = x[..., 0] + x[..., 2] / 2
    y[..., 3] = x[..., 1] + x[..., 3] / 2
    return y

# Draw object boxes
def draw_object_boxes(data):
    
    img, obj_box_list, class_list = data
    
    for i, (obj_box, class_name) in enumerate(zip(obj_box_list, class_list)):
        obj_box = xywh2xyxy_np(obj_box)
        x1, y1, x2, y2 = list(map(int, obj_box))
        
        print(f'x1/y1/x2/y2: {x1}, {y1}, {x2}, {y2}')
        print(f'class idx: {class_name}')
        
        color = (0, 0, 255)
        thickness = 2
        
        t_size = cv2.getTextSize(class_name, cv2.FONT_HERSHEY_PLAIN, 2 , 2)[0]
        cv2.rectangle(img, (x1, y1), (x2, y2), color, thickness)
        cv2.rectangle(img, (x1, y1), (x1+t_size[0]+3, y1+t_size[1]+4), color, -1)
        cv2.putText(img, class_name, (x1, y1+t_size[1]+4), cv2.FONT_HERSHEY_PLAIN, 2, [255,255,255], 2)

        imshow(img)

draw_object_boxes(copy.deepcopy(data))<jupyter_output>x1/y1/x2/y2: 385, 60, 600, 357
class idx: giraffe
x1/y1/x2/y2: 53, 356, 185, 411
class idx: giraffe
{'fraction_non_alphanumeric': 0.13449564134495642, 'fraction_numerical': 0.05105853051058531, 'mean_word_length': 3.3369330453563717, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '568041', 'license': 'MIT', 'n_tokens_mistral': 1646, 'n_tokens_neox': 1522, 'n_words': 358, 'path': 'visualization_object_detection.ipynb', 'repo_name': 'qbxlvnf11/object-detection-visualization', 'size': '4015'}