0
votes

I have two sets of matching points, eg.

# first set of points
[[696.0, 971.3333333333334], [1103.3333333333333, 934.6666666666666], ...]
# second set of points
[[475.0, 458.6666666666667], [1531.3333333333333, 524.0], ...]

from two images. Right now I'm using this piece of code to align images:

points_source = np.array(source_coordinates)
points_destination = np.array(destination_coordinates)

h, status = cv2.findHomography(points_destination, points_source, cv2.RANSAC)
aligned_image = cv2.warpPerspective(destination_image, h, (source_image.shape[1], source_image.shape[0]))

It works well most of the time, but sometimes it warps image and it aligns bad. I found estimateRigidTransform function, that'd be the best for me, because it's possible to only translate and rotate the image, but it's deprecated and when I try to use it, it throws an error:

Traceback (most recent call last):
  File "align.py", line 139, in <module>
    align(image, image2, source_coordinates, destination_coordinates)
  File "align.py", line 111, in align
    m = cv2.estimateRigidTransform(points_destination, points_source, fullAffine=False)
AttributeError: module 'cv2' has no attribute 'estimateRigidTransform'

I couldn't find any other solution than estimateRigidTransform. Is there any other function that'd work for me? Maybe I can use warpPerspective to only change rotation and translation? I don't want to use getAffineTransform function because it can accept only three points and I want to use much more points. My OpenCV version is 4.0.1-1

2
You can't use cv2.estimateRigidTransform()? It works for me on OpenCV version 4.0.0-pre.Stephen Meschke
@StephenMeschke no, I can't, it throws an error on 4.0.1-1hamster121

2 Answers

1
votes

The function I needed is: cv2.estimateAffinePartial2D()

0
votes

Instead of using plain OpenCV, I would recommend to link your project with another library that has the algorithms you are looking (for and much more). Probably the best solution would be Insight Toolkit library (ITK) or Visual Toolkit (VTK). The former is much complex and also much harder to learn, but the latter is actually very simple. They both use CMake and there is no problem in compiling/linking etc.

ITK is especially designed for image processing. It includes so called Landmark based registration, which is exactly what you need. Complete working example is available. Unfortunately, the library seems very complex at the beginning.

On the other hand, VTK also implements the same algorithm, but it can be used very simply (From the example):

vtkSmartPointer<vtkLandmarkTransform> landmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
landmarkTransform->SetSourceLandmarks(sourcePoints);
landmarkTransform->SetTargetLandmarks(targetPoints);
landmarkTransform->SetModeToRigidBody();
landmarkTransform->Update();
std::cout << landmarkTransform->GetMatrix() << std::endl;