How to align images?

I have two grayscale images (img1, img2) which contain objects seen with two cameras. Some objects are the same (not same shape and intensity) and are seen in both images. Some objects are only seen in img1 or img2.

I would like to align the images in such a way that the objects seen in both images are overlapping.

How can I determine the vertical and horizontal shift between the two images?

Here are the images:

img1:

img2:

What I tried:

pts = ImageCorrespondingPoints[img1, img2, KeypointStrength -> 0.0002]

{{{34.6035, 72.9785}}, {{48.1733, 82.9132}}}

xshift = Mean[pts[[All, All, 1]][[2]] - pts[[All, All, 1]][[1]]]

13.5698

yshift = Mean[pts[[All, All, 2]][[2]] - pts[[All, All, 2]][[1]]]

9.93468


This seems to be correct. When I look only at the vertically elongated object in the center of img2 then I find manually roughly: xshift=10, yshift=13.

What confuses me:

The found points pts do not correspond to img1 or img2:

HighlightImage[img1, pts]


HighlightImage[img2, pts]


Where is the error in HighlightImage?

Can ImageCorrelate or ImageAlign be used to find the shift or do you have another solution?

My solution is the following:

Determine the shift between both images:

{merit, trans} =
FindGeometricTransform[img2, img1,
TransformationClass -> "Translation"];


Applying the shifts

imgt = ImageTransformation[img2, trans, DataRange -> Full]


Combine images

Blend[{ColorNegate[img1], imgt}, {0.8, 0.2}]


• very interesting ...
– mrz
Jun 23, 2017 at 9:26
• In the documentation the TransformFunction obtained from FindGeometricTransform is a transformation which if you apply to the second image in the argument of FindGeometricTransform (in this case img1) you get an image which is aligned with the image in the first argument (here img2). However, it seems it the other way around and by applying the TransformationFunction on the first argument you align it with the image in the second argument. Is this right?
– MOON
May 23, 2020 at 10:48

Using ImageFeatureTrack works pretty well:

{f1, f2} = ImageFeatureTrack[{img1, img2}];
HighlightImage[img1, f1]
HighlightImage[img2, f2]


Now calculate the offset:

shift = Mean[
Cases[f1 - f2, {x_, y_} /; NumericQ[x] && NumericQ[y]]
];


And compose the images. I used ColorNegate so you can see what's going on:

ImageCompose[
img1,
{ColorNegate[img2], 0.5},
shift,
{0, 0}
]


• great solution, thanks
– mrz
Jun 21, 2017 at 14:40