import cv2 import numpy as np import json rotation_map = { 0: None, 90: cv2.ROTATE_90_COUNTERCLOCKWISE, 180: cv2.ROTATE_180, 270: cv2.ROTATE_90_CLOCKWISE } class NumpyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) def draw_bboxes(image, bounding_boxes, boxes_id, scores): image_with_boxes = image.copy() for bbox, bbox_id, score in zip(bounding_boxes, boxes_id, scores): x1, y1, x2, y2 = bbox cv2.rectangle(image_with_boxes, (x1, y1), (x2, y2), (128, 128, 0), 2) label = f'#{bbox_id}: {score:.2f}' (label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1) label_x = x1 label_y = y1 - 5 if y1 > 20 else y1 + 20 # Draw a filled rectangle as the background for the label cv2.rectangle(image_with_boxes, (x1, label_y - label_height - 5), (x1 + label_width, label_y + 5), (128, 128, 0), cv2.FILLED) cv2.putText(image_with_boxes, label, (label_x, label_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) return image_with_boxes def pad_image(image: np.ndarray, aspect_ratio: float) -> np.ndarray: # Get the current aspect ratio of the image image_height, image_width = image.shape[:2] current_aspect_ratio = image_width / image_height left_pad = 0 top_pad = 0 # Determine whether to pad horizontally or vertically if current_aspect_ratio < aspect_ratio: # Pad horizontally target_width = int(aspect_ratio * image_height) pad_width = target_width - image_width left_pad = pad_width // 2 right_pad = pad_width - left_pad padded_image = np.pad(image, pad_width=((0, 0), (left_pad, right_pad), (0, 0)), mode='constant') else: # Pad vertically target_height = int(image_width / aspect_ratio) pad_height = target_height - image_height top_pad = pad_height // 2 bottom_pad = pad_height - top_pad padded_image = np.pad(image, pad_width=((top_pad, bottom_pad), (0, 0), (0, 0)), mode='constant') return padded_image, (left_pad, top_pad) class VideoReader(object): def __init__(self, file_name, rotate=0): self.file_name = file_name self.rotate = rotation_map[rotate] try: # OpenCV needs int to read from webcam self.file_name = int(file_name) except ValueError: pass def __iter__(self): self.cap = cv2.VideoCapture(self.file_name) if not self.cap.isOpened(): raise IOError('Video {} cannot be opened'.format(self.file_name)) return self def __next__(self): was_read, img = self.cap.read() if not was_read: raise StopIteration if self.rotate is not None: img = cv2.rotate(img, self.rotate) return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)