1. Background Knowledge
Haar-like features, introduced in the Viola-Jones face detection framework, are simple rectangular filters that capture local intensity differences to detect edges, lines, and textures in images. They enable rapid feature computation across scales using Integral Images (also called summed-area tables), which precompute prefix sums for constant-time rectangular region queries.
The Integral Image I(x,y) for a grayscale image i(x,y) is defined as:
I(x,y)=x′=0∑xy′=0∑yi(x′,y′)
This allows the sum over any rectangle (x0,y0) to (x1,y1) (inclusive) via:
Sum=I(x1,y1)+I(x0−1,y0−1)−I(x1,y0−1)−I(x0−1,y1)
Boundary handling: For x<0 or y<0, I(x,y)=0.
A vertical 2-rectangle Haar filter has two adjacent rectangles: positive RP (e.g., left) and negative RN (e.g., right), with equal width and height. Response = Sum(RP)−\text{Sum}(RN), highlighting vertical edges.
Prerequisites: 0-based indexing, grayscale images with non-negative pixels, basic 2D array access.
2. Algorithm Approach
Use direct rectangle sum queries on the given Integral Image I (no need to compute it). For each region defined by [x0,y0,x1,y1]:
- Implement a rect_sum(x0, y0, x1, y1) function using the 4-lookup formula, clamping invalid indices to 0.
- Compute Sum(RP) and Sum(RN).
- Return Sum(RP)−\text{Sum}(RN) as integer.
This is the core of Viola-Jones efficiency: O(1) per feature regardless of rectangle size.
Pseudocode:
def rect_sum(I, x0, y0, x1, y1):
def safe_get(x, y):
return I[y][x] if 0 <= x < len(I) and 0 <= y < len(I) else 0
return (safe_get(x1, y1) + safe_get(x0-1, y0-1)
- safe_get(x1, y0-1) - safe_get(x0-1, y1))
def haar_response(I, Rp, Rn): # Rp, Rn: [x0,y0,x1,y1]
return rect_sum(I, *Rp) - rect_sum(I, *Rn)
3. Step-by-Step Strategy
- Parse inputs: Extract coordinates for RP and RN (assume provided as lists/arrays).
- Implement safe lookup: Handle out-of-bounds by returning 0 (per constraints).
- Compute rectangle sums: Apply the integral formula twice.
- Calculate response: Subtract sums; cast to int if needed.
- Test edge cases: Empty regions (x0>x1), negative coordinates, full-image spans.
Vertical filter example: RP=[2,1,3,4] (left), RN=[4,1,5,4] (right).
4. Common Pitfalls
- Off-by-one errors: Formula assumes inclusive corners; x0−1,y0−1 must be correctly clamped.
- Index order: Images are row-major (I[y][x]); confuse x/y.
- No bounds check: Accessing I[−1] crashes; always use safe_get.
- Sign flip: Ensure positive minus negative (not reverse).
- Floating-point: Output must be integer; sums are integers by constraint.
- Assuming 1-based: Problem specifies 0-based.
5. Time & Space Complexity
- Time: O(1) per response (4 lookups), ideal for real-time detection (e.g., 160k+ features/sec in Viola-Jones).
- Space: O(1) extra (uses existing I, size O(HW) where H,W are image dimensions).
This scales to thousands of filters over large images, enabling classifiers like AdaBoost.