import numpy as np import cv2 def sigmoid(x): return 1 / (1 + np.exp(-x)) def xywh2xyxy(x): # x has shape [n, 4] where each row is (center_x, center_y, width, height) y = np.zeros_like(x) y[:, 0:2] = x[:, 0:2] - x[:, 2:4] / 2 # calculate min_x, min_y y[:, 2:4] = x[:, 0:2] + x[:, 2:4] / 2 # calculate max_x, max_y return y def iou(box, boxes): # Compute xmin, ymin, xmax, ymax for both boxes xmin = np.maximum(box[0], boxes[:, 0]) ymin = np.maximum(box[1], boxes[:, 1]) xmax = np.minimum(box[2], boxes[:, 2]) ymax = np.minimum(box[3], boxes[:, 3]) # Compute intersection area intersection_area = np.maximum(0, xmax - xmin) * np.maximum(0, ymax - ymin) # Compute union area box_area = (box[2] - box[0]) * (box[3] - box[1]) boxes_area = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) union_area = box_area + boxes_area - intersection_area # Compute IoU iou = intersection_area / union_area return iou def fast_nms(boxes, scores, iou_threshold): sorted_indices = np.argsort(scores)[::-1] selected_indices = [] while sorted_indices.size > 0: box_id = sorted_indices[0] selected_indices.append(box_id) if sorted_indices.size == 1: break remaining_boxes = boxes[sorted_indices[1:]] current_box = boxes[box_id].reshape(1, -1) ious = np.array([iou(current_box[0], remaining_box) for remaining_box in remaining_boxes]) keep_indices = np.where(ious < iou_threshold)[0] sorted_indices = sorted_indices[keep_indices + 1] return selected_indices