Warp image by keypoints

Hi, I use keypoints to match the orientation of 2 images.

src_pts = np.float32([ kp1[m.queryIdx].pt for m in matches ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in matches ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC)
h,w,d = img1.shape
warped = cv2.warpPerspective(img2, M, (w, h))

Is there a function that warps only 2d? Sometimes due to lack of keypoints or wrong keypoints the function is changing the z axis, I want it to stay untouched.
Thanks in advance!

there’s estimateAffine2D and estimateAffinePartial2D

Thanks a lot for your reply. Unfortunately this doesnt do exactly what I expected. Parts of the Image are now perfectly warped, others are disorted. With my functions I managed to perfectly rotate the image by x and y axis if I could only remove the z rotation from the rotation matrix.

can you show what you mean?

Left is the original image. Right is after estimateAffine2D, the Text in the middle is perfectly oriented, the rest is absolutely not.

estimateAffinePartial2D is way better but still there are gaps

and how do you generate the feature descriptors and the matching? what’s the reference you are matching against?

I’m asking to see the source and the reference picture as well as some illustration of the keypoint match pairs.

it all looks like the methods perform precisely as they should, i.e. it’s exactly an affine or lesser transformation.

oh by the way, did you notice that your magazine cover is physically warped? did you expect to correct that with nothing but an affine transformation? not even a perspective transform (homography) can fix that because everything assumes plane-to-plane transformations, while your magazine cover isn’t a plane anymore.

here you see the first page after the cover peek through because the cover sheet is wavy.

Yes you are right, maybe I expected too much for wavy sheets. There are no keypoint matches in these regions so thats why it kind of changes the perspective in these areas. I tested estimateAffinePartial2D on a large dataset and it seems to work really well with less messed up covers. Thanks a lot!