import type { Image } from '../../Image.js'; import { getClockwiseAngle } from '../../maskAnalysis/utils/getAngle.js'; import { toDegrees } from '../../utils/geometry/angles.js'; import { getRadius } from '../../utils/getRadius.js'; import { checkBorderDistance } from '../utils/checkBorderDistance.js'; import type { FastKeypoint, GetFastKeypointsOptions, } from './getFastKeypoints.js'; import { getFastKeypoints } from './getFastKeypoints.js'; import { getPatchIntensityCentroid } from './getPatchIntensityCentroid.js'; export interface GetOrientedFastKeypointsOptions extends GetFastKeypointsOptions { /** * Diameter of the circle used for computation of the intensity centroid. * @default `7` */ centroidPatchDiameter?: number; } export interface OrientedFastKeypoint extends FastKeypoint { /** * Orientation of the keypoint defined as the angle in degrees between the x axis , the keypoints origin and the center of mass of the keypoint. */ angle: number; } /** * Find the oriented FAST features in a GREY image. * How to add orientation to FAST is described in: http://www.gwylab.com/download/ORB_2012.pdf * Basically, the intensity centroid of the window around the corner is computed and the * orientation is given by the vector from the center to the intensity centroid. * @param image - The image to process. * @param options - Get oriented FAST keypoints options. * @returns The oriented FAST keypoints. */ export function getOrientedFastKeypoints( image: Image, options: GetOrientedFastKeypointsOptions = {}, ): OrientedFastKeypoint[] { const { centroidPatchDiameter: windowSize = 7 } = options; const fastKeypoints = getFastKeypoints(image, options); const radius = getRadius(windowSize); // handle edge cases: remove keypoints too close to border const keypoints: FastKeypoint[] = []; for (const keypoint of fastKeypoints) { if (checkBorderDistance(image, keypoint.origin, radius)) { keypoints.push(keypoint); } } const orientedFastKeypoints: OrientedFastKeypoint[] = []; for (const keypoint of keypoints) { const centroid = getPatchIntensityCentroid(image, { center: keypoint.origin, radius, })[0]; const angle = toDegrees(getClockwiseAngle({ column: 0, row: 0 }, centroid)); orientedFastKeypoints.push({ ...keypoint, angle }); } return orientedFastKeypoints; }