OpenCV仿射变换无法执行

7

我正在尝试使用枢轴点执行基本的仿射变换。

import cv2
import numpy as np
import PIL
import matplotlib.pyplot as plt

img = cv2.imread('earth.png')
img_pivots = cv2.imread('earth_keys.png')
map_img = cv2.imread('earth2.png')
map_pivots = cv2.imread('earth2_keys.png')

pts_img_R = np.transpose(np.where(img_pivots[:, :, 2] > 0 ))
pts_img_G = np.transpose(np.where(img_pivots[:, :, 1] > 0 ))
pts_img_B = np.transpose(np.where(img_pivots[:, :, 0] > 0 ))
pts_img = np.vstack([pts_img_R, pts_img_G, pts_img_B])
pts_map_R = np.transpose(np.where(map_pivots[:, :, 2] > 0 ))
pts_map_G = np.transpose(np.where(map_pivots[:, :, 1] > 0 ))
pts_map_B = np.transpose(np.where(map_pivots[:, :, 0] > 0 ))
pts_map = np.vstack([pts_map_R, pts_map_G, pts_map_B])

M = cv2.estimateRigidTransform(pts_map.astype(np.float32), pts_img.astype(np.float32), True)

dst = cv2.warpAffine(map_img,M,(img.shape[1], img.shape[0]))

plt.subplot(121),plt.imshow(img),plt.title('earth.png')
plt.subplot(122),plt.imshow(dst),plt.title('earth2.png transrofmed')
plt.show()

在两张图片上,我标记了3个点(R、G和B),并将它们保存在单独的图像中('earth.png'的'earth_keys.png'和'earth2.png'的'earth2_keys.png')。我想要做的就是将'earth2.png'上的枢轴点与'earth.png'上的枢轴点匹配。

然而,在转换后,我得到的只有这个 enter image description here

我想我错放了一些参数之类的东西,但我尝试过所有的组合,得到了各种错误的结果,但仍然找不到问题所在。

示例图像(带枢轴)

编辑: 将枢轴数更改为6

仍然是错误的转换 enter image description here

M现在等于

 array([[  4.33809524e+00,   8.28571429e-01,  -5.85633333e+02],
   [ -6.22380952e+00,  -1.69285714e+00,   1.03468333e+03]])

具有6个枢轴的示例


请问您能否尝试使用超过3个点?有一些刚性变换可以允许最少3个点,但是OpenCV有一个“fullAffine”参数。如果设置了这个参数,我认为就会有超过6个自由度。您能告诉我们M的结果值吗? - Micka
刚刚检查了一下,6自由度应该对于fullAffine来说没问题,所以3个点对应该没问题。请打印并添加M。 - Micka
添加了另外3个枢轴并编辑了问题,但仍然有些问题。您是否使用相同的代码? - arkhy
1个回答

6

你对于支点的把握有多大?

如果我在你的图片上标出支点,结果如下图所示:

Plotting points

手动叠加后,效果类似于你的结果:

Manual superposition

如果我手动确定三个对应点,得到的结果如下:

pts_img = np.vstack([[68,33],   [22,84],  [113,87]] )
pts_map = np.vstack([[115,101], [30,199], [143,198]])

手动点的结果

虽然还不完美,但可能更接近你想要的效果。

总之,我建议你检查如何计算关键点,如果有疑问,进行手动叠加


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接