Skip to content

API‐Feature‐Detection

ZangoTech edited this page Jun 20, 2026 · 1 revision

Feature Detection

← Back to API Reference · Home

Namespace: acl::feature (CPP) / acl::neon::feature (NEON)

Common data structures (in the acl:: namespace):

struct KeyPoint      { int x, y; float response; };
struct KeyPointORB   { float x, y, response, scale, angle; uint8_t descriptor[32]; };
struct KeyPointExt   { float x, y, response, scale, angle; float descriptor[128]; };
struct Point2f       { float x, y; };
struct DMatch        { int queryIdx, trainIdx; float distance; };
struct Vec2f         { float val[2]; };    // (rho, theta)
struct Vec3f         { float val[3]; };    // (cx, cy, radius)
struct Vec4i         { int val[4]; };      // (x1, y1, x2, y2)

FAST Corner Detection

FAST corner detection (Bresenham 16-pixel circle comparison).

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int fastCornerDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    int threshold = 20,
    bool nonmaxSuppress = true,
    int type = 9);
Parameter Type Meaning Default
srcImage const uint8_t* Input grayscale image non-null
srcStride int Bytes per row 0 = width
keypoints vector<KeyPoint>& Output corners
threshold int Grayscale difference threshold 20
nonmaxSuppress bool Whether to perform NMS true
type int FAST-N (9 or 12; N is the number of consecutive pixels) 9

Harris Corner Detection

Harris corner detection. Response R = det(M) - k * trace(M)^2, where M is the structure tensor.

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

// Detect corners (including NMS)
int harrisCornerDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    int blockSize = 2,
    float k = 0.04f,
    float threshold = 1e6f);

// Emit the Harris response map only (caller does the threshold / NMS) — CPP only
int harrisResponse(
    const uint8_t* srcImage, float* dstImage,
    int width, int height, int srcStride,
    int blockSize = 2, float k = 0.04f);
Parameter Type Meaning Default
blockSize int Structure-tensor neighborhood radius 2
k float Harris free parameter 0.04
threshold float Minimum response threshold 1e6

Shi-Tomasi Corner Detection

Shi-Tomasi corners (Good Features to Track): response = min(λ1, λ2) (the structure tensor's eigenvalues).

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int shiTomasiCornerDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    int maxCorners = 500,
    float qualityLevel = 0.01f,
    float minDistance = 10.0f,
    int blockSize = 2);

// Alias (same semantics as shiTomasiCornerDetect)
int shiTomasiDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& corners,
    int maxCorners = 500,
    float qualityLevel = 0.01f,
    float minDistance = 10.0f,
    int blockSize = 2);

// Emit the min-eigenvalue response map only — CPP only
int minEigenValResponse(
    const uint8_t* srcImage, float* dstImage,
    int width, int height, int srcStride,
    int blockSize = 2);
Parameter Type Meaning Default
maxCorners int Upper bound on returned corners (0 = no limit) 500
qualityLevel float Minimum quality ratio relative to the strongest response 0.01
minDistance float Minimum Euclidean distance between adjacent corners 10.0
blockSize int Structure-tensor neighborhood radius 2

ORB (Oriented FAST and Rotated BRIEF)

ORB detection + 256-bit rBRIEF descriptors.

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

// Detect + compute descriptors
int orbDetectAndCompute(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPointORB>& keypoints,
    int maxKeypoints = 500,
    float scaleFactor = 1.2f,
    int nLevels = 8,
    int fastThreshold = 20);

// Detection only (discard descriptors, output KeyPoint)
int orbDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    int maxKeypoints = 500,
    float scaleFactor = 1.2f,
    int nLevels = 8,
    int fastThreshold = 20);

// Hamming distance between two 256-bit descriptors (0-256)
int orbHammingDistance(const uint8_t desc1[32], const uint8_t desc2[32]);
Parameter Type Meaning Default
maxKeypoints int Target keypoint count 500
scaleFactor float Inter-level pyramid scale factor (> 1.0) 1.2
nLevels int Number of pyramid levels 8
fastThreshold int FAST internal threshold 20

srcWidth / srcHeight must be ≥ 32.


SIFT (Scale-Invariant Feature Transform)

SIFT scale-invariant features + 128-D descriptors.

Tier: Business
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int siftDetectAndCompute(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPointExt>& keypoints,
    int nOctaves = 0,
    int nScalesPerOctave = 3,
    float contrastThresh = 0.04f,
    float edgeThresh = 10.0f,
    float sigma = 1.6f);

// Detection only
int siftDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    int nOctaves = 0, int nScalesPerOctave = 3,
    float contrastThresh = 0.04f, float edgeThresh = 10.0f,
    float sigma = 1.6f);
Parameter Type Meaning Default
nOctaves int Number of pyramid octaves (0 = auto log2(min(w,h)) - 2) 0
nScalesPerOctave int Scales per octave 3
contrastThresh float DoG extremum contrast threshold 0.04
edgeThresh float Edge-response rejection threshold 10.0
sigma float Initial Gaussian sigma 1.6

srcWidth / srcHeight must be ≥ 16.


SURF (Speeded-Up Robust Features)

SURF accelerated features. Integral image + Hessian determinant; outputs 128-D descriptors (the first 64 dimensions of keypoints.descriptor are used).

Tier: Business
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int surfDetectAndCompute(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPointExt>& keypoints,
    float hessianThresh = 100.0f,
    int nOctaves = 4,
    int nOctaveLayers = 3);

// Detection only
int surfDetect(
    const uint8_t* srcImage, int width, int height, int srcStride,
    std::vector<KeyPoint>& keypoints,
    float hessianThresh = 100.0f,
    int nOctaves = 4, int nOctaveLayers = 3);

srcWidth / srcHeight must be ≥ 24.


HOG (Histogram of Oriented Gradients)

HOG descriptor — histogram of gradient orientations; commonly used for pedestrian detection and classification features.

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

struct HOGParams {
    int cellSize;    // default 8
    int blockSize;   // default 2 (block = blockSize × blockSize cells)
    int nbins;       // default 9
    int blockStride; // default 1 (in units of cells)
};

int computeHOG(
    const uint8_t* srcImage, int width, int height, int srcStride,
    float* descriptors, int& descriptorSize,
    const HOGParams& params = HOGParams());
Parameter Type Meaning Default
descriptors float* Output descriptor array (pre-allocated by the caller) non-null
descriptorSize int& Returns the actual number of floats written
params const HOGParams& HOG parameters default-constructed

Output size = blocksX * blocksY * (blockSize * blockSize * nbins). You can estimate this in advance using the default parameters or by calling once to read descriptorSize.


houghLines / houghLinesP

Standard Hough line detection (houghLines outputs (rho, theta)) and probabilistic Hough (houghLinesP outputs line-segment endpoints).

Tier: Pro+
Channels: 1ch binary edge map (typically produced by canny)
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

// Standard Hough
int houghLines(
    const uint8_t* edgeImage, int width, int height, int stride,
    std::vector<acl::Vec2f>& lines,
    float rho,
    float theta,
    int threshold);

// Probabilistic Hough (returns line segments)
int houghLinesP(
    const uint8_t* edgeImage, int width, int height, int stride,
    std::vector<acl::Vec4i>& lines,
    float rho,
    float theta,
    int threshold,
    double minLineLength,
    double maxLineGap);
Parameter Type Meaning Recommended
edgeImage const uint8_t* Input binary edge image (non-zero = edge) non-null
rho float Distance resolution (pixels) 1.0
theta float Angle resolution (radians) M_PI/180
threshold int Accumulator vote threshold standard 100 / probabilistic 50
minLineLength double (probabilistic only) minimum line length 0
maxLineGap double (probabilistic only) maximum gap between two points on the same line 10

Output:

  • houghLinesVec2f(rho, theta)
  • houghLinesPVec4i(x1, y1, x2, y2)

houghCircles

Hough circle detection (21HT gradient method).

Tier: Pro+
Channels: 1ch grayscale image (internally performs Canny + gradient, no pre-binarization needed)
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int houghCircles(
    const uint8_t* grayImage, int width, int height, int stride,
    std::vector<acl::Vec3f>& circles,
    float dp = 1.0f,
    float minDist = 20.0f,
    float param1 = 100.0f,
    float param2 = 100.0f,
    int minRadius = 0,
    int maxRadius = 0);
Parameter Type Meaning Default
grayImage const uint8_t* Input grayscale image non-null
circles vector<Vec3f>& Output circles (cx, cy, radius)
dp float Accumulator-to-image resolution ratio 1.0
minDist float Minimum distance between adjacent circle centers 20.0
param1 float Canny upper threshold (lower threshold auto = param1 / 2) 100.0
param2 float Accumulator threshold for circle-center detection 100.0
minRadius int Minimum radius 0
maxRadius int Maximum radius (0 = max(width, height)) 0

opticalFlowLK

Sparse pyramid Lucas-Kanade optical flow.

Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t

CPP / NEON Signature (identical)

int opticalFlowLK(
    const uint8_t* prevImage, const uint8_t* nextImage,
    int width, int height, int stride,
    const acl::Point2f* prevPts, acl::Point2f* nextPts,
    uint8_t* status, float* error,
    int numPoints,
    int winSize = 21,
    int maxLevel = 3,
    int maxIter = 30,
    float epsilon = 0.01f);
Parameter Type Meaning Default
prevImage, nextImage const uint8_t* Previous / next frames non-null
prevPts const Point2f* Points in the previous frame to be tracked non-null
nextPts Point2f* Tracked points in the next frame (caller pre-allocates numPoints) non-null
status uint8_t* Per-point status (1 = tracking succeeded, 0 = lost; pre-allocated for numPoints) non-null
error float* Per-point tracking error (may be nullptr; when non-null, pre-allocated for numPoints) nullable
numPoints int Number of tracked points
winSize int Search window size 21
maxLevel int Maximum pyramid level 3
maxIter int Max iterations per level 30
epsilon float Convergence threshold 0.01

descriptorMatch (bfMatch / bfMatchBinary / bfKnnMatch / bfKnnMatchBinary)

Brute-force descriptor matching: bfMatch* returns 1 nearest neighbor per query; bfKnn* returns K nearest neighbors. The float version uses L2 distance; the Binary version uses Hamming distance.

Tier: Pro+
Channels: N/A (descriptor vectors)
Inplace: not supported
Types:

Template parameter Allowed types Constraint
T uint8_t binary descriptors (e.g. ORB)
T float real-valued descriptors (e.g. SIFT/SURF)

CPP / NEON Signature (identical)

// float descriptors, L2 distance, 1-NN
int bfMatch(
    const float* queryDescs, int queryCount, int descDim,
    const float* trainDescs, int trainCount,
    std::vector<acl::DMatch>& matches);

// Binary descriptors (e.g. ORB), Hamming distance, 1-NN
int bfMatchBinary(
    const uint8_t* queryDescs, int queryCount, int descBytes,
    const uint8_t* trainDescs, int trainCount,
    std::vector<acl::DMatch>& matches);

// float descriptors, L2, K-NN
int bfKnnMatch(
    const float* queryDescs, int queryCount, int descDim,
    const float* trainDescs, int trainCount,
    std::vector<std::vector<acl::DMatch>>& matches,
    int k = 2);

// Binary descriptors, Hamming, K-NN
int bfKnnMatchBinary(
    const uint8_t* queryDescs, int queryCount, int descBytes,
    const uint8_t* trainDescs, int trainCount,
    std::vector<std::vector<acl::DMatch>>& matches,
    int k = 2);
Parameter Type Meaning
queryDescs, trainDescs const float* / const uint8_t* Row-major descriptors, length Count × (descDim or descBytes)
descDim int float descriptor dimension (SIFT 128; the SURF implementation uses 64)
descBytes int Binary descriptor byte count (ORB 32)
matches vector<DMatch>& or vector<vector<DMatch>>& Output matches; each DMatch contains queryIdx, trainIdx, distance
k int K for K-NN (actually returns min(k, trainCount))

Example

uint8_t srcImage[1920*1080];
std::vector<acl::KeyPointORB> kps;

// 1) ORB detection + description
acl::neon::feature::orbDetectAndCompute(
    srcImage, 1920, 1080, 0, kps);

// 2) ORB matching between two images (Binary + Hamming)
std::vector<uint8_t> qDescs(kps.size() * 32), tDescs(/*...*/);
for (size_t i = 0; i < kps.size(); ++i)
    memcpy(qDescs.data() + i*32, kps[i].descriptor, 32);

std::vector<acl::DMatch> matches;
acl::neon::feature::bfMatchBinary(
    qDescs.data(), (int)kps.size(), 32,
    tDescs.data(), /*trainCount=*/200,
    matches);

Clone this wiki locally