Non Maximum Suppression (NMS)#


Overview#
Non Maximum Suppression (NMS) is a crucial post-processing step in object detection to reduce the number of overlapping bounding boxes for the same object. The goal is to select the most appropriate bounding box that tightly encloses an object while suppressing weaker, overlapping detections.
Steps Involved in NMS#
Score Sorting: Begin by sorting all the detected bounding boxes based on their confidence scores in descending order.
Selection: Select the bounding box with the highest confidence score and mark it as the best detection.
IoU Calculation: Calculate the Intersection over Union (IoU) between this selected bounding box and the rest of the bounding boxes.
Suppression: Remove bounding boxes that have an IoU greater than a predefined threshold (e.g., 0.5) with the selected bounding box.
Iteration: Repeat steps 2-4 for the remaining bounding boxes.
Mathematical Representation#
Let \( B_i \) be a bounding box and \( S_i \) its associated confidence score. The IoU between two bounding boxes \( B_i \) and \( B_j \) is given by:
Pseudocode for NMS#
def nms(bounding_boxes, confidence_scores, threshold):
# Sort the bounding boxes by confidence scores in descending order
sorted_indices = sorted(range(len(confidence_scores)), key=lambda k: confidence_scores[k], reverse=True)
keep_boxes = []
while sorted_indices:
# Select the bounding box with the highest confidence score
current_idx = sorted_indices.pop(0)
keep_boxes.append(current_idx)
# Calculate IoU and suppress boxes with IoU above the threshold
filtered_indices = []
for idx in sorted_indices:
iou = calculate_iou(bounding_boxes[current_idx], bounding_boxes[idx])
if iou < threshold:
filtered_indices.append(idx)
sorted_indices = filtered_indices
return keep_boxes
def calculate_iou(box1, box2):
# Calculate the intersection area
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
intersection_area = max(0, x2 - x1) * max(0, y2 - y1)
# Calculate the union area
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
union_area = box1_area + box2_area - intersection_area
# Calculate IoU
return intersection_area / union_area
Real-World Example#
Imagine you are detecting pedestrians in a crowded street scene. The detector might identify multiple bounding boxes around the same person due to variations in scales and positions. NMS helps in selecting the most accurate bounding box for each pedestrian while suppressing the redundant ones.
Visualization#
Suppose an image contains several detected bounding boxes for a single object, like a car:
Multiple bounding boxes of various sizes and positions may overlap around the car.
NMS selects the bounding box with the highest confidence score and suppresses others with significant overlap.
The final result is a single bounding box accurately representing the car’s position.
Importance in Object Detection#
Reduces Redundancy: Eliminates multiple detections for the same object, improving the clarity of results.
Enhances Precision: Ensures that the highest confidence detection is selected, enhancing the model’s precision.
Computational Efficiency: By reducing the number of bounding boxes, NMS also helps in speeding up subsequent processing steps.