Hamming Distance Matcher
Implement feature matching using Hamming distance for binary descriptors. This task involves finding the best matches between two sets of binary feature descriptors.
The Hamming distance is a measure of the number of positions at which two binary strings differ, given by dHβ(a,b)=βiβaiββbiβ. It is used to compare the similarity between binary descriptors.
To perform matching:
- For each descriptor in set A, find the nearest neighbor in set B
- Apply the ratio test: accept if best_dist/second_best_dist<threshold
This technique is widely used in computer vision for feature matching and object recognition.
Example:
desc1 = [[1,0,1,0], [0,1,0,1]] desc2 = [[1,0,1,1], [0,0,0,0], [0,1,0,1]] ratio_threshold = 0.75
[(0, 0, 1), (1, 2, 0)]
Descriptor 0 from image 1:
- dist to desc2[0]: 1 bit differs
- dist to desc2[1]: 2 bits differ
- dist to desc2[2]: 4 bits differ Best=1, second=2, ratio=0.5 < 0.75 β Match: (0,0)
Descriptor 1 from image 1:
- dist to desc2[2]: 0 bits differ (exact match!) Ratio test passes trivially for exact matches.
Constraints:
- desc1: Binary descriptors from image 1 (N1, D)
- desc2: Binary descriptors from image 2 (N2, D)
- ratio_threshold: Ratio test threshold (default 0.75)
- Return: List of (idx1, idx2, distance) matches
More from CV: Feature Detection and Matching
Youβre implementing brute-force feature matching for binary descriptors using Hamming distance plus Loweβs ratio test. Conceptually, this is exactly how ORB/BRIEF/FREAK descriptors are typically matched in CV libraries: binary descriptors are compared bitwise, and nearest-neighbor matches are accepted only if the best match is clearly better than the second best (ratio test), which helps reject ambiguous or repetitive features.
Binary descriptors encode local image patterns as bit strings (e.g., 256 bits), where each bit is the result of a simple intensity comparison test around a keypoint. Matching then becomes efficient because Hamming distance can be computed with a fast XOR + popcount on machine words. The ratio test, introduced by Lowe in SIFT, generalizes here: even though SIFT uses Euclidean distance and ORB/BRIEF use Hamming, the idea is the sameβfeatures that have similarly good multiple matches are unreliable and should be discarded.
1. Background Knowledge
- Binary descriptors & Hamming distance A binary descriptor is a fixed-length bit vector, often represented as an array of bytes/ints. The Hamming distance between two descriptors a and b of the same length is:
where aiββbiβ=1 if bits differ and 0 otherwise, so dHβ counts differing bits.
-
Nearest-neighbor matching Given two sets of descriptors A={a1β,β¦,amβ} and B = \{b_1,\dots,b_n\},asimplematcherfinds,foreacha_i,theββnearestneighborββinBw.r.t.Hammingdistance(andalsothesecondnearest).ThisisusuallydoneviaabruteβforcescanoveralldescriptorsinB$.
-
Loweβs ratio test for ambiguity Many keypoints may look similar (e.g., in repetitive textures). If the best and second-best matches have very similar distances, the match is ambiguous. Loweβs ratio test keeps a match only if:
Typical thresholds are around 0.7β0.8 (problem may specify). This dramatically reduces false matches, at the cost of discarding some good ones.
2. Algorithm / General Approach
The standard pattern for binary descriptor matching with ratio test:
- For each descriptor in A, compare it to all descriptors in B.
- Compute Hamming distance for each pair using XOR + popcount over all words of the descriptor.
- Track the smallest and second smallest distances for that query descriptor.
- Apply ratio test: if best_dist / second_best_dist < threshold, accept the pair (index_in_A, index_of_best_in_B) as a match.
- Collect all accepted matches into a list.
This is a brute-force O(β£Aβ£β β£Bβ£) NN search in Hamming space, which is acceptable for typical contest constraints unless the sets are huge.
3. Step-by-Step Strategy
Assume you have:
- A: list/array of descriptors, shape [NA][D]
- B: list/array of descriptors, shape [NB][D] Where each descriptor is a binary string stored as bytes/ints (e.g., vector<uint8_t> or vector<uint32_t>).
Step 1: Hamming distance function
Implement a function to compute Hamming distance between two descriptors:
- Represent each descriptor as an array of machine words (8-bit/32-bit/64-bit).
- For each word index k:
- xor_word = a[k] ^ b[k]
- count += popcount(xor_word) (use built-in bit-popcount if available).
- Return the total count.
Example in C++-like pseudocode:
int hammingDist(const uint8_t* a, const uint8_t* b, int bytes) {
int dist = 0;
for (int i = 0; i < bytes; ++i) {
uint8_t x = a[i] ^ b[i];
dist += __builtin_popcount((unsigned)x); // or custom popcount
}
return dist;
}
Continue the full explanation
You're reading the free preview. Unlock the complete walkthrough, the code editor, test runner and reference solution with Premium.
Editor locked
The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.