ImageKeypoints[image]
finds key features in image and returns their coordinates.
ImageKeypoints[image,prop]
gives the specified property prop for each keypoint.
ImageKeypoints[video,…]
finds keypoints in frames of video.
ImageKeypoints
ImageKeypoints[image]
finds key features in image and returns their coordinates.
ImageKeypoints[image,prop]
gives the specified property prop for each keypoint.
ImageKeypoints[video,…]
finds keypoints in frames of video.
Details and Options
- Image keypoints are distinct positions on an image highlighting specific image features such as shape, contrast, orientation. Corresponding keypoints are typically used for aligning images.
- ImageKeypoints[image] finds image keypoints and returns their positions as a list of {{x1,y1},{x2,y2},…}.
- The following properties can be specified:
-
"Confidence" blob response, given as a positive number "ContrastSign"
if the keypoint is lighter than its surroundings,
otherwise"Descriptor" keypoint descriptor "Orientation" orientation angle, given in radians "OrientedDescriptor" keypoint-oriented descriptor "PixelPosition" pixel coordinates {x,y} in the range
, 
"Position" image coordinates {x,y} in the range
,
(default)"Scale" keypoint scale - ImageKeypoints sorts the results based on the "Confidence" property of the keypoints.
- ImageKeypoints[image,{prop1,prop2,…}] returns multiple properties.
- The feature descriptors returned by ImageKeypoints are numerically robust against translation, rotation, and scale changes.
- The following options can be specified:
-
KeypointStrength 0 minimum strength of the keypoints Masking All region of interest MaxFeatures All maximum number of keypoints Method "SURF" type of keypoint to return - With a setting MaxFeatures->n, at most n keypoints with largest "Confidence" are returned.
- Possible method settings include:
-
"AGAST" Adaptive and Generic Accelerated Segment Test "AKAZE" Accelerated KAZE and binary descriptors "BRISK" Binary Robust Invariant Scalable Keypoints "FAST" Features from Accelerated Segment Test "KAZE" nonlinear scale-space detector and descriptor "ORB" FAST detector and Binary Robust Independent Elementary Features (BRIEF) descriptor "SIFT" Scale-Invariant Feature Transform detector and descriptor "RootSIFT" SIFT keypoints with an improved descriptor "SURF" Speeded-Up Robust Features - When a property is not available with a specified method, the corresponding element in the result is set to Missing["NotAvailable"]. »
Examples
open all close allBasic Examples (2)
Scope (10)
Keypoints of a grayscale image:
ImageKeypoints[[image]]//ShortImageKeypoints[[image]]//ShortImageKeypoints[[image]]Return the keypoint descriptor:
ImageKeypoints[[image], "Descriptor"]ImageKeypoints[[image], {"Scale", "Orientation", "ContrastSign"}]//MatrixFormGet properties "Position" and "PixelPosition":
pos = ImageKeypoints[[image], {"Position", "PixelPosition"}]The two corresponding coordinate systems are offset by half a pixel:
pos[[All, 1]] + 1 / 2 == pos[[All, 2]]img = [image];scales = ImageKeypoints[img, "Scale"]The scale corresponds to the size of an intrinsic region around the keypoint. Visualize the disc region
around a "SURF" keypoint:
HighlightImage[img, {Thick, MapThread[Circle, {ImageKeypoints[img, "Position"], 2.5 * scales}]}, ImageSize -> 100]Get the "Orientation" in radians:
img = [image];orient = ImageKeypoints[img, "Orientation"]Show keypoints with a pattern rotated based on orientation:
HighlightImage[img,
MapThread[
{Circle[#2, 5], Line[{#2, #2 + 5 * {Cos[#1], Sin[#1]}}]}&,
{orient, ImageKeypoints[img]}],
ImageSize -> 200]img = [image];
strength = ImageKeypoints[img, "Confidence"];
strength//ShortDisplay the distribution of the strength of keypoints in an image:
Histogram@strengthGet the "Descriptor" representing the distribution of pixel values inside a keypoint's neighborhood:
img = [image];desc1 = ImageKeypoints[img, "Descriptor", MaxFeatures -> 1];The descriptor is similar to the one of the rotated image:
desc2 = ImageKeypoints[ImageRotate@img, "Descriptor", MaxFeatures -> 1];EuclideanDistance[desc1, desc2]The "ConstrastSign" is 1 for keypoints lighter than their surroundings:
ImageKeypoints[[image], "ContrastSign"]The sign is -1 for keypoints darker than their surroundings:
ImageKeypoints[[image], "ContrastSign"]Options (11)
KeypointStrength (1)
Masking (1)
MaxFeatures (1)
Method (8)
By default, "SURF" keypoints are computed:
i = [image];HighlightImage[i, ImageKeypoints[i]]Compute and visualize a different keypoint:
HighlightImage[i, ImageKeypoints[i, Method -> "AKAZE", MaxFeatures -> 80]]"FAST" and "AGAST" keypoints are defined by their location and strength at scale 3.5:
i = [image];ImageKeypoints[i, {"Position", "Confidence", "Scale"}, Method -> "FAST", MaxFeatures -> 50]//ShortCompute and visualize FAST keypoints:
HighlightImage[i, ImageKeypoints[i, Method -> "FAST", MaxFeatures -> 50]]Compute and visualize AGAST keypoints:
HighlightImage[i, ImageKeypoints[i, Method -> "AGAST", MaxFeatures -> 50]]"BRISK" and "ORB" keypoints are defined by their location, scale, orientation and strength:
img = [image];{brisk, orb} = ImageKeypoints[img, {"Position", "Scale", "Orientation", "Confidence"}, Method -> #]& /@ {"BRISK", "ORB"};RandomSample[brisk, 2]RandomSample[orb, 2]Descriptors are vectors of 0s and 1s of length 512 for "BRISK" and 256 for "ORB":
{brisk, orb} = ImageKeypoints[img, "Descriptor", Method -> #]& /@ {"BRISK", "ORB"};brisk[[1]]//Shortorb[[1]]//ShortDimensions[#]& /@ {brisk, orb}"AKAZE" and "KAZE" keypoints are defined by their location, scale, orientation and strength:
img = [image];{akaze, kaze} = ImageKeypoints[img, {"Position", "Scale", "Orientation", "Confidence"}, Method -> #]& /@ {"AKAZE", "KAZE"};RandomSample[akaze, 2]RandomSample[kaze, 2]AKAZE descriptors are vectors of 0s and 1s of length 480:
ImageKeypoints[img, "Descriptor", Method -> "AKAZE"]//ShallowDimensions[%]KAZE descriptors are vectors of 128 real numbers with unit norm:
ImageKeypoints[img, "Descriptor", Method -> "KAZE"]//Short{Dimensions[%], Norm /@ RandomSample[%, 5]}AKAZE oriented descriptors are computed without correcting for keypoints' intrinsic orientation:
img = [image];{kod, orientations} = Transpose@ImageKeypoints[img, {"OrientedDescriptor", "Orientation"}, Method -> "AKAZE"];Oriented descriptors match descriptors for keypoints with orientation close to 0:
δ = MapThread[HammingDistance, {kod, ImageKeypoints[img, "Descriptor", Method -> "AKAZE"]}];Pick[orientations, δ, x_ /; x < 20]With the "SURF" method, a keypoint is defined by its location, scale, orientation, contrast sign and strength:
img = [image];surf = ImageKeypoints[img, {"Position", "Scale", "Orientation", "ContrastSign", "Confidence"}];RandomSample[surf, 2]SURF descriptors consist of vectors of 64 real numbers with unit norm:
ImageKeypoints[img, "Descriptor", Method -> "SURF"]//Short{Dimensions[%], Norm /@ RandomSample[%, 5]}Oriented descriptors match descriptors for keypoints with orientation close to 0:
{kod, orientations} = Transpose@ImageKeypoints[img, {"OrientedDescriptor", "Orientation"}];δ = MapThread[EuclideanDistance, {kod, ImageKeypoints[img, "Descriptor"]}];Pick[orientations, δ, x_ /; x < 0.15]The "SIFT" method uses Scale-Invariant Feature Transform to find the location of image keypoints:
img = [image];ImageKeypoints[img, {"Position", "Scale", "Orientation", "Confidence"}, Method -> "SIFT"];
RandomSample[%, 2]The descriptors use histograms of orientations to construct vectors of 128 numbers:
desc = ImageKeypoints[img, "Descriptor", Method -> "SIFT"];Short /@ RandomSample[desc, 2]Note that the norm of the descriptor is not equal to one:
Norm /@ RandomSample[desc, 5]The "RootSIFT" method uses the same keypoints locations as "SIFT", but improved descriptors:
ImageKeypoints[[image], "Descriptor", Method -> "RootSIFT"]//ShortNorm of RootSIFT descriptors is equal to one:
Norm /@ %//ShortApplications (5)
Visualize SURF keypoints using their scale, orientation and contrast:
img = [image];
points = ImageKeypoints[img, {"Position", "Scale", "Orientation", "ContrastSign"}, MaxFeatures -> 100];
scalefactor = 2.5;
HighlightImage[img, Table[{{If[p[[4]] == 1, Yellow, Red], Circle[p[[1]], p[[2]] * scalefactor], Line[{p[[1]], p[[1]] + p[[2]] * scalefactor * {Cos[p[[3]]], Sin[p[[3]]]}}]}}, {p, points}]]img = [image];points = ImageKeypoints[img, {"Position", "Scale", "Orientation"}, Method -> "BRISK", MaxFeatures -> 50];
HighlightImage[img, {FaceForm[], Table[Rotate[{Line[{p[[1]], p[[1]] + p[[2]] * {1, 0}}], Rectangle[p[[1]] + p[[2]] * {-1, -1}, p[[1]] + p[[2]] * {1, 1}]}, p[[3]]], {p, points}]}]Extract local patches of fixed size around detected keypoints:
img = [image];
ImageTrim[img, {#}, 12]& /@ ImageKeypoints[img, Method -> "KAZE", MaxFeatures -> 100]Extract patches of size proportional to the scale of keypoints:
{pos, size} = Transpose@ImageKeypoints[img, {"Position", "Scale"}, Method -> "KAZE", MaxFeatures -> 100];
MapThread[ImageTrim[img, {#1}, 2 * #2]&, {pos, size}]Use keypoints to crop an image to keep the main features:
imgs = {[image], [image], [image]};
ImageTrim[#, ImageKeypoints[#, KeypointStrength -> .0005], 50]& /@ imgsCreate thumbnails of uniform size:
ImageCrop[ImageResize[#, {{240}, {180}}], {240, 180}]& /@ %Object recognition using "bag of words" on a dataset of 5,000 images 32×32 each, belonging to 10 categories:
obj = ResourceObject["CIFAR-10"];
training = ResourceData[obj, "TrainingData"];
testing = Flatten[Table[training[[i + 1000 ;; i + 1099]], {i, 1, 50000, 5000}]];training = Flatten[Table[training[[i ;; i + 499]], {i, 1, 50000, 5000}]];Compute keypoint descriptors on 256×256 images and create the codebook of visual words:
AbsoluteTiming[
kp = ParallelTable[
ImageKeypoints[ImageResize[i, 256], "Descriptor"], {i, training[[All, 1]]}
];]The codebook contains all image descriptors of length 64:
codebook = Flatten[kp, 1];
Dimensions[codebook]Find 100 visual codewords using
-means clustering:
AbsoluteTiming[
clust = ClusteringComponents[codebook, 100, 1, Method -> "KMeans", PerformanceGoal -> "Speed"];]codewords = Table[
p = Flatten@Position[clust, i];
Mean[codebook[[p]]],
{i, Max@clust}];Image features are defined as the normalized counts of all the codewords:
nf = Nearest[codewords -> Automatic];imageCodewordsFeatureExtract[image_ ? ImageQ] := imageCodewordsFeatureExtract[ImageKeypoints[ImageResize[image, {256, 256}], "Descriptor"]];
imageCodewordsFeatureExtract[keypoints_List] := Module[
{h},
h = N@BinCounts[First@nf[#, 1] & /@ keypoints, {1, Length@codewords + 1}];
h / Total[h]
];imageCodewordsFeatureExtract[RandomSample[training][[1, 1]]]//HistogramConstruct a classifier trained on extracted image features:
t = Table[imageCodewordsFeatureExtract[kp[[i]]] -> training[[i, 2]],
{i, Length@training}];classifier = Classify[t];Evaluate the classifier on test data:
cm = ClassifierMeasurements[classifier, Table[imageCodewordsFeatureExtract[First@sample] -> Last@sample, {sample, testing}]];cm["ConfusionMatrixPlot"]Properties & Relations (7)
Not all properties are supported for all methods:
Missing["NotAvailable"] is returned when a property is not available with the specified method:
ImageKeypoints[[image], {"Position", "Descriptor"}, Method -> "FAST", MaxFeatures -> 5]"FAST" method does not find contrast sign:
ImageKeypoints[[image], {"Position", "ContrastSign"}, Method -> "AGAST", MaxFeatures -> 4]"BRISK" method does not compute oriented descriptors:
ImageKeypoints[[image], {"Position", "OrientedDescriptor"}, Method -> "BRISK", MaxFeatures -> 4]"SURF" and "KAZE" descriptors are typically compared using the Euclidean distance:
img = [image];kp = ImageKeypoints[img, {"Position", "Descriptor"}, MaxFeatures -> 11, Method -> "KAZE"];Distances between the strongest keypoint and each of the next 10 strongest:
best = kp[[1, 2]];
distances = Table[EuclideanDistance[best, d], {d, kp[[2 ;; , 2]]}]"AKAZE", "BRISK" and "ORB" descriptors are typically compared using the Hamming distance:
kp = ImageKeypoints[img, {"Position", "Descriptor"}, MaxFeatures -> 11, Method -> "BRISK"];Distances between the strongest keypoint and each of the next 10 strongest:
best = kp[[1, 2]];
distances = Table[HammingDistance[best, d], {d, kp[[2 ;; , 2]]}]Cluster the keypoints based on their descriptors:
img = [image];
k = ImageKeypoints[img, {"Position", "Descriptor"}, MaxFeatures -> 80];
clust = FindClusters[k[[All, 2]] -> k[[All, 1]], 3];
colors = ColorData[3] /@ Range[Length[clust]];
HighlightImage[img, Transpose[{colors, clust}]]ImageCorners may be used as keypoints:
img = [image];Computer corners using radius 3.5 for similarity to the scale of some keypoint detectors:
corners = ImageCorners[img, 3.5, MaxFeatureDisplacement -> 1, MaxFeatures -> 10]HighlightImage[img, {White, corners}]Use CornerFilter to get the strength of detected corners:
cf = CornerFilter[img, 3.5];
strengths = ImageValue[cf, corners];
Transpose[{corners, strengths}]ImageKeypoints[img, {"Position", "Confidence"}, Method -> "FAST", MaxFeatures -> 10]ImageKeypoints[img, {"Position", "Confidence"}, Method -> "AGAST", MaxFeatures -> 10]ImageCorrespondingPoints gives the locations for keypoints that have matching descriptors:
{img1, img2} = {[image], [image]};{pos1, pos2} = ImageCorrespondingPoints[img1, img2];MapThread[HighlightImage, {{img1, img2}, {pos1, pos2}}]Compute keypoints on both images:
{k1, k2} = ImageKeypoints[#, {"Position", "Descriptor"}, MaxFeatures -> 100]& /@ {img1, img2};Take two keypoints with and without a corresponding point in the second image:
{m, n} = {k1[[23]], k1[[24]]};Compute all distances between descriptors for these keypoint to all keypoints in the second image:
δm = EuclideanDistance[m[[2]], #]& /@ k2[[All, 2]];
δn = EuclideanDistance[n[[2]], #]& /@ k2[[All, 2]];Histogram[#, ImageSize -> 200]& /@ {δm, δn}The second-to-nearest ratio is typically used to decide whether a keypoint has a corresponding point:
{bestm, secondbestm} = TakeSmallestBy[k2, EuclideanDistance[m[[2]], #[[2]]]&, 2];
{bestn, secondbestn} = TakeSmallestBy[k2, EuclideanDistance[n[[2]], #[[2]]]&, 2];EuclideanDistance[m[[2]], secondbestm[[2]]] / EuclideanDistance[m[[2]], bestm[[2]]]EuclideanDistance[n[[2]], secondbestn[[2]]] / EuclideanDistance[n[[2]], bestn[[2]]]The keypoint with a correspondence is red; the other one is yellow:
{HighlightImage[img1, {Red, m[[1]], Yellow, n[[1]]}, ImageSize -> 250],
HighlightImage[img2, {White, k2[[All, 1]], Yellow, bestn[[1]], Red, bestm[[1]]}, ImageSize -> 250]}History
Introduced in 2010 (8.0) | Updated in 2012 (9.0) ▪ 2014 (10.0) ▪ 2017 (11.1) ▪ 2021 (13.0) ▪ 2025 (14.2)
Text
Wolfram Research (2010), ImageKeypoints, Wolfram Language function, https://reference.wolfram.com/language/ref/ImageKeypoints.html (updated 2025).
CMS
Wolfram Language. 2010. "ImageKeypoints." Wolfram Language & System Documentation Center. Wolfram Research. Last Modified 2025. https://reference.wolfram.com/language/ref/ImageKeypoints.html.
APA
Wolfram Language. (2010). ImageKeypoints. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/ref/ImageKeypoints.html
BibTeX
@misc{reference.wolfram_2026_imagekeypoints, author="Wolfram Research", title="{ImageKeypoints}", year="2025", howpublished="\url{https://reference.wolfram.com/language/ref/ImageKeypoints.html}", note=[Accessed: 13-June-2026]}
BibLaTeX
@online{reference.wolfram_2026_imagekeypoints, organization={Wolfram Research}, title={ImageKeypoints}, year={2025}, url={https://reference.wolfram.com/language/ref/ImageKeypoints.html}, note=[Accessed: 13-June-2026]}