image-js
Version:
Image processing and manipulation in JavaScript
70 lines (61 loc) • 2.27 kB
text/typescript
import type { BriefDescriptor } from '../descriptors/getBriefDescriptors.js';
import {
sortByDestSource,
sortBySourceDest,
} from '../utils/sortBySourceDest.js';
import type { Match } from './bruteForceMatch.js';
import { bruteForceOneMatch } from './bruteForceMatch.js';
/**
* Get the crosscheck matches from the source and destination descriptors.
* @param source - Source descriptors.
* @param destination - Destination descriptors.
* @returns The array of crossckeck matches.
*/
export function getCrosscheckMatches(
source: BriefDescriptor[],
destination: BriefDescriptor[],
): Match[] {
const srcMatches = bruteForceOneMatch(source, destination);
const dstMatches = bruteForceOneMatch(destination, source);
return crosscheck(srcMatches, dstMatches);
}
/**
* Return the indices of pairs the keypoints that are mutually the best match.
* This means that if B is the best match for A, A should be the best match for B.
* The distance of the resulting matches is the maximum distance between the two.
* @param srcDstMatches - Best matches computed from source do destination.
* @param dstSrcMatches - Best matches computed from destination to source.
* @returns The pairs of keypoints that are mutually the best match.
*/
export function crosscheck(
srcDstMatches: Match[],
dstSrcMatches: Match[],
): Match[] {
const result: Match[] = [];
const sortedSrcDst = sortBySourceDest(srcDstMatches);
const sortedDstSrc = sortByDestSource(dstSrcMatches);
let pointer1 = 0;
let pointer2 = 0;
while (pointer1 < sortedSrcDst.length && pointer2 < sortedDstSrc.length) {
const match1 = sortedSrcDst[pointer1];
const match2 = sortedDstSrc[pointer2];
if (match1.sourceIndex > match2.destinationIndex) {
pointer2++;
} else if (match1.sourceIndex < match2.destinationIndex) {
pointer1++;
} else if (match1.destinationIndex > match2.sourceIndex) {
pointer2++;
} else if (match1.destinationIndex < match2.sourceIndex) {
pointer1++;
} else {
result.push({
distance: Math.max(match1.distance, match2.distance),
sourceIndex: match1.sourceIndex,
destinationIndex: match1.destinationIndex,
});
pointer1++;
pointer2++;
}
}
return result;
}