Corner and Keypoint Detection
Corners and keypoints are distinct image regions that can be tracked across frames or matched between views, acting as stable anchors for vision tasks.
Why Does This Exist?
Stitching a panorama, tracking a car across frames, or rebuilding a scene in 3D all need the same thing: reference points that can be found again in another image. Comparing every pixel of image A against every pixel of image B is hopeless — slow, and shattered by small shifts in light or viewpoint.
The fix is sparse, distinctive anchors called keypoints. Corners are the best simple keypoint: unlike a flat patch (nothing changes anywhere) or an edge (nothing changes along its length), a corner changes sharply in every direction, so it localizes precisely in both axes. Harris made them cheap to find; SIFT later made them survive zoom. This page covers what makes a good keypoint and how Harris scores one. The detector's own page is Harris corner detector, zoom-proof features are in scale-invariant feature transform, and joining the matches is feature matching for image stitching.
The one idea you need first
An image gradient measures how fast brightness changes horizontally and vertically at a pixel. Flat ground has near-zero gradients, an edge has a strong gradient across it but none along it, and a corner has strong gradients in both — the whole detector below is bookkeeping on these two numbers.
Think of It Like This
Matching jigsaw pieces of empty sky
Two puzzle pieces of flat blue sky cannot be aligned — no feature pins them. Pieces crossed by one straight contrail slide along it: one direction fixed, one free. But pieces sharing the sharp corner where a cloud cuts the sky snap together instantly in both directions.
Flat regions shift invisibly, edges shift along themselves, corners shift nowhere without showing it. That is the entire ranking Harris computes. The analogy stops at uniqueness: a real corner is only useful if its neighbourhood looks different from every other corner's, which is why repetitive brickwork defeats matching despite firing thousands of detections.
How It Actually Works
Harris slides a conceptual window and asks how much the patch would change if shifted. Instead of shifting, it builds the structure tensor from summed gradient products over the window, weighted toward the center:
Here and are the horizontal and vertical gradients, and is typically a Gaussian weight. The two eigenvalues of tell the story: both small means flat, one large means edge, both large means corner. To skip the eigenvalue computation, Harris scores the response directly from determinant and trace:
with , , and . Corners score large and positive, edges negative, flat ground near zero — one threshold separates all three.
Worked example
Take with . Determinant , trace , so : strongly positive, a corner. Its eigenvalues are , i.e. and — both large, as claimed.
Contrast an edge, : determinant , trace , , negative. And flat ground, : , near zero. Harris himself is rotation-invariant (spinning the image spins both eigenvectors together) but not scale-invariant: zoom in and the corner becomes a curve. SIFT fixes that with an image pyramid.
Code
The worked example in NumPy — response scores and the eigenvalues they stand in for:
import numpy as np
k = 0.04
def harris_R(M: np.ndarray) -> float: det = float(np.linalg.det(M)) trace = float(np.trace(M)) return det - k * trace**2
corner = np.array([[4.0, 1.0], [1.0, 3.0]])print(round(harris_R(corner), 2)) # -> 9.04print(np.round(np.linalg.eigvalsh(corner), 3)) # -> [2.382 4.618]
edge = np.array([[5.0, 0.0], [0.0, 0.1]])print(round(harris_R(edge), 2)) # -> -0.54Positive and large means corner, negative means edge — the sign does the classifying before any threshold is even applied.
Watch Out For
Scale change silently deleting every match
Harris windows have one fixed size, so a corner in a wide shot becomes a smooth curve in a close-up and the detector goes blind. The symptom is two overlapping photos with hundreds of detections each and zero accepted matches.
Switch to a scale-invariant detector such as SIFT or ORB whenever zoom or distance varies between views; reserve Harris for fixed-scale video tracking.
Repetitive texture drowning the matcher
Brick walls, chessboards and fences fire thousands of strong corners whose neighbourhoods look identical. The symptom is a matcher that returns confident correspondences that are geometrically nonsense.
Detect densely but match strictly: keep Lowe's ratio test tight, demand geometric consensus with RANSAC, and treat match count without consensus as no matches at all.
The Quick Version
- Keypoints are sparse, distinctive anchors used to match views, track motion and rebuild 3D.
- Corners beat edges and flat patches because brightness changes sharply in every direction.
- Harris builds a structure tensor from gradients and scores R from determinant minus k times trace squared.
- R is large positive for corners (9.04), negative for edges (-0.54), near zero for flat ground.
- Harris survives rotation but not zoom; SIFT adds scale invariance with an image pyramid.
- Repetitive texture needs strict ratio tests and RANSAC, not more detections.