Detect and localize multiple objects in images
Object detection goes beyond classification - it identifies multiple objects and their locations in images. **Key Concepts:** - **Bounding Boxes**: (x, y, width, height) coordinates - **Confidence Scores**: Probability of detection - **IoU (Intersection over Union)**: Measures overlap - **Non-Maximum Suppression (NMS)**: Removes duplicate detections **Popular Architectures:** - YOLO (You Only Look Once): Real-time detection - SSD (Single Shot Detector): Fast and accurate - Faster R-CNN: Two-stage detector with high accuracy
Basic detection logic:
import numpy as np
def compute_iou(box1, box2):
"""
Compute Intersection over Union (IoU) of two bounding boxes
box format: [x1, y1, x2, y2]
"""
# Intersection coordinates
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
intersection = max(0, x2 - x1) * max(0, y2 - y1)
# Union area
area1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
union = area1 + area2 - intersection
# IoU
iou = intersection / union if union > 0 else 0
return iou
def nms(boxes, scores, iou_threshold=0.5):
"""
Non-Maximum Suppression
boxes: list of [x1, y1, x2, y2]
scores: confidence scores
"""
# Sort by confidence
indices = np.argsort(scores)[::-1]
keep = []
while len(indices) > 0:
# Keep box with highest score
current = indices[0]
keep.append(current)
# Compute IoU with remaining boxes
ious = np.array([compute_iou(boxes[current], boxes[i])
for i in indices[1:]])
# Keep only boxes with IoU below threshold
indices = indices[1:][ious < iou_threshold]
return keep
# Example: Multiple detections
boxes = np.array([
[100, 100, 200, 200], # Box 1
[110, 110, 210, 210], # Box 2 (overlaps with 1)
[300, 300, 400, 400], # Box 3 (separate)
[105, 105, 205, 205], # Box 4 (overlaps with 1 & 2)
])
scores = np.array([0.9, 0.75, 0.8, 0.7])
print("Before NMS:")
for i, (box, score) in enumerate(zip(boxes, scores)):
print(f" Box {i+1}: {box}, Score: {score}")
# Apply NMS
keep_indices = nms(boxes, scores, iou_threshold=0.5)
print(f"\nAfter NMS (IoU threshold = 0.5):")
for idx in keep_indices:
print(f" Box {idx+1}: {boxes[idx]}, Score: {scores[idx]}")
# Compute some IoU examples
print(f"\nIoU Examples:")
print(f" Box 1 vs Box 2: {compute_iou(boxes[0], boxes[1]):.3f}")
print(f" Box 1 vs Box 3: {compute_iou(boxes[0], boxes[2]):.3f}")
print(f" Box 1 vs Box 4: {compute_iou(boxes[0], boxes[3]):.3f}")Before NMS: Box 1: [100 100 200 200], Score: 0.9 Box 2: [110 110 210 210], Score: 0.75 Box 3: [300 300 400 400], Score: 0.8 Box 4: [105 105 205 205], Score: 0.7 After NMS (IoU threshold = 0.5): Box 1: [100 100 200 200], Score: 0.9 Box 3: [300 300 400 400], Score: 0.8 IoU Examples: Box 1 vs Box 2: 0.681 Box 1 vs Box 3: 0.000 Box 1 vs Box 4: 0.795