Multiple Image Features detected with SIFT causing issues finding estimated transform

I am finding, extracting, and matching features from two MRI images of differing modalities. I am looking at axial slices from the two MRI datasets and comparing them. I applied a 2D transformation matrix A to one of the series of images. The goal is to estimate my applied transformation matrix A by matching features. Some of these are poorly matched and do not have many matching features. I know that some of these are poorly matched, that is okay.
After conducting extractFeatures, I get some repeat points in the validPoints (p2) object. After matchFeatures, I check to make sure that there are more than 2 matched features in order to use estgeoform2d() between the two sets, and then fitgeoform2d() to the inliers. However, after that, sometimes the inliers are repeated points, and does not give 3 non-colinear points required for the fitgeoform2d().
My question is:
  • Why can extractFeatures return repeated valid points?
  • If I want to only keep one of the valid points (such that I only have unique valid points), how do I know which one and which SIFT Feature to choose (in the features array)
  • How do the repeated points impact estimating translation? How can I have the best outcome?
  • When should I normalize my images? is mat2gray a good normalization option?
Here is my code: Keep in mind, I have 2 arrays (img1, img2) that are 217x181x181, and I am sifting through the z axis (axial slices) from z = 45:155 to remove poor edge cases. I have cell arrays since each slice will have a different number of points and features. I normalize my images using mat2gray before slicing and after slicing.
CODE:
nSlices = length([45:155]);
%initialize cell arrays
[p1, ft1, p2, ft2, pairs, A, ins] = deal(cell(nSlices, 1));
[in_ratio, stats] = deal(zeros(nSlices,1));
%normalize entire 271x181x181 data
img1 = mat2gray(img1);
img2 = mat2gray(img2);
for k = 1:nSlices
%extract and normalize slice
slice = mat2gray(img1(:,:,k+44));
pt1{k} = detectSIFTFeatures(slice);
[ft1{k}, p1{k}] = extractFeatures(slice, pt1{k}, Method='SIFT');
slice2 = mat2gray(img2(:,:,k+44));
pt2{k} = detectSIFTFeatures(slice2);
[ft2{k}, p2{k}] = extractFeatures(slice2, pt2{k}, Method='SIFT');
%match slice and slice2 features
pairs{k} = matchFeatures(ft1{k}, ft2{k},'MatchThreshold',...
20.0, 'MaxRatio', 0.8, 'Unique', true);
%ensure more than 2 matches
if length(pairs{k}) > 2
%extract matched points. match1 and match2 are both SIFT
%objects
match1 = p1{k}(pairs{k}(:,1),:);
match2 = p2{k}(pairs{k}(:,2),:);
%estimate the translation matrix, find inliers
[~, ins{k}] = estgeotform2d(match1, match2, 'affine',...
'MaxNumTrials', 4000, 'MaxDistance',3);
%build translation estimate from inliers
t_est = fitgeotform2d(match1.Location(ins{k},:), ...
match2.Location(ins{k},:), 'affine');
A{k} = t_est.A;
in_ratio(k) = nnz(ins{k})/length(ins{k});
end
end

3 Comments

As a note, after estgeoform2d(), I may get 3 unique points from my match1 vector, but only 2 unique points from match2. How can I pick the 'better' match? Is the location part of the SIFTPoint the best thing to pass into fitgeoform2d()?
Hard to say just looking at a bunch of code. And we can't run it because you didn't supply img1 and img2. I know they're probably big 3-D arrays but you could upload just a pair of slices and then do just one iteration of the loop to demonstrate the problem.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:

Sign in to comment.

Answers (0)

Products

Release

R2025b

Asked:

on 11 Apr 2026 at 15:24

Commented:

about 10 hours ago

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!