8.14.4 EP08_04 🟢 IoU and Non-Maximum Suppression (NMS)
The figure in this section showed the effect of Non-Maximum Suppression on a set of boxes produced by a sliding window detector: multiple redundant detections per object were reduced to a single box per object. You were tasked with reimplementing, byte by byte, the two functions that produced that result — calcular_iou and supressao_nao_maximos — to confirm, with your own hands, exactly the numbers presented in the chapter.
8.14.4.1 📋 Implementation Guidelines
Input: Read the integer \(N\) (number of boxes) and the real \(\tau\) (IoU threshold). Then read \(N\) lines, each with five reals \(x_{min}\ y_{min}\ x_{max}\ y_{max}\ \text{score}\).
Intersection over Union: For two boxes \(A\) and \(B\), \[ \mathrm{IoU}(A,B) = \frac{\text{area}(A \cap B)}{\text{area}(A \cup B)}, \] with the intersection area being zero when the boxes do not overlap.
NMS Algorithm (exactly as described in the chapter):
Sort the boxes by
scorein descending order (ties preserve the original reading order).Select the highest-scoring box among the remaining ones; add it to the output and remove it from the list.
Discard from the remaining list all boxes whose IoU with the selected box is greater than or equal to \(\tau\) — only boxes with \(\mathrm{IoU} < \tau\) remain as candidates.
Repeat steps (b)–(c) until the list of remaining boxes is empty.
Output: For each retained box, in the order it was selected, print its original index (reading position, starting from \(0\)) and its
score, with 2 decimal places. At the end, printTotal mantidas: X.
8.14.4.2 📌 Computational Constraints
- Attention to the direction of the threshold: contrary to what one might assume, a box is suppressed when \(\mathrm{IoU} \ge \tau\) (not only when \(\mathrm{IoU} > \tau\)) — follow exactly this criterion, the same as the chapter’s reference code.
- Original indices: the output references the reading position of each box in the input, not its position after sorting by
score. - Area without the +1 pixel adjustment: use area \(= (x_{max}-x_{min}) \times (y_{max}-y_{min})\), exactly as in the chapter (without the “+1” adjustment sometimes used in other conventions).
8.14.4.3 🧠 Theoretical Foundation
| Element | Role in Post-Processing |
|---|---|
| IoU | Quantifies the spatial overlap between two bounding boxes |
| Sliding window (Haar Cascade) | Typically produces multiple overlapping detections for the same object, at nearby positions and scales |
| Threshold \(\tau\) | Controls the aggressiveness of suppression: too low merges nearby objects; too high lets redundancies pass |
Sorting by score |
Ensures that, among redundant boxes, the one with the highest confidence always survives |
8.14.4.4 📦 Input and Output Specification (VPL)
Input:
- Line 1: Integer \(N\) and real \(\tau\).
- Next \(N\) lines: five reals \(x_{min}\ y_{min}\ x_{max}\ y_{max}\ \text{score}\).
Output:
- One line per retained box, in selection order:
index score(score with 2 decimal places). - Last line:
Total mantidas: X.
8.14.4.5 📌 Examples
| Input | Output | Observation |
|---|---|---|
| 5 0.4 50 50 150 150 0.90 60 55 155 145 0.75 58 60 160 150 0.60 300 300 400 420 0.95 310 305 395 415 0.70 |
3 0.95 0 0.90 Total mantidas: 2 |
Exactly the example from the chapter’s figure: 5 redundant boxes (2 objects) become 2 final detections. The IoU between the 1st and 2nd boxes is \(\approx 0.775\), well above \(\tau=0.4\). |
%%writefile EP08_04.py
# Python codeOverwriting EP08_04.py
TestSuite("EP08_04.py").run()✔️ EP08_04.cases already exists in casos/
📋 6 case(s) loaded from casos/EP08_04.cases
🔍 Testing Python: EP08_04.py
⚠️ EP08_04.py: Empty file (fewer than 3 lines). Tests skipped.