【问题标题】:Mapping sets of points with affine transformation使用仿射变换映射点集
【发布时间】:2020-02-11 17:04:38
【问题描述】:

有2组点:

这些点在单独的 pandas 数据帧 (python 3) 中,存储为行中的点和列中 x 和 y 位置的值:

Centroid X µm   Centroid Y µm

0 1243.4, 662.69

1 1254.5, 666.70

我已经匹配了不同程序中的点,该程序为我提供了将覆盖两个图的仿射变换矩阵:

-0.002, -1.000, 19629.301,

1.000, -0.002, 3414.193

但是,其他程序不允许我保存转换后的图像,这就是我在这里提取点的原因。所以我想将此仿射变换矩阵应用于其中一个数据帧的这两列,以便点重叠。

【问题讨论】:

  • 当你说它们必须被归一化、旋转和翻转时,这是否意味着你已经想到了一个特定的转换,或者它应该是优化中的一个参数? (后者要复杂得多。)
  • 抱歉拖了这么久,我已经更新了问题。我想到的转换被列为转换矩阵。我已经在给我变换矩阵的程序中直观地优化了变换,因此不需要进一步的优化参数。

标签: python-3.x pandas numpy scikit-image affinetransform


【解决方案1】:

我们可以将pandas 数据帧转换为numpy 数组,估计仿射变换并应用估计的变换如下:

# randomly-generated sample datapoints
data1 =  np.random.multivariate_normal(mean=np.zeros(2), cov=[[10,0],[0,1]], size=1000)
data2 = np.zeros_like(data1)
# apply an affine transform, 
# e.g., apply rotation + translation
# to transform data1 into data2 
# (could apply shear / scaling here too)
tx, ty, theta = 2, -2, np.pi/6
print(tx, ty, theta)
# 2 -2 0.5235987755982988
data2[:,0] = data1[:,0]*np.cos(theta)-data1[:,1]*np.sin(theta) + tx
data2[:,1] = data1[:,0]*np.sin(theta)+data1[:,1]*np.cos(theta) + ty
# visualize the datasets

现在使用skimage.tramsform 中的estimate_transform() 使用最小二乘法估计仿射变换:

from skimage.transform import estimate_transform
tform = estimate_transform('affine', data1, data2)
par = tform.params
print(par) # the estimated affine transformation matrix (in homogeneous coordinates)
# [[ 0.8660254 -0.5        2.       ]
# [ 0.5        0.8660254 -2.       ]
# [ 0.         0.         1.       ]]
tx_, ty_ = par[0,-1], par[1,-1]
theta_ = np.arccos(par[0,0])
print(tx_, ty_, theta_)
# 1.9999999999999996 -1.9999999999999993 0.5235987755982978

从上面注意到,估计的参数非常接近原始仿射变换参数。

现在使用估计的参数将data1 转换为data2_ 并可视化。

data2_ = np.zeros_like(data1)
data2_[:,0] = data1[:,0]*np.cos(theta_)-data1[:,1]*np.sin(theta_) + tx_
data2_[:,1] = data1[:,0]*np.sin(theta_)+data1[:,1]*np.cos(theta_) + ty_
plt.scatter(data1[:,0], data1[:,1], alpha=0.2, label='data1')
plt.scatter(data2_[:,0], data2_[:,1], alpha=0.2, label='data2 estimated')
plt.legend()

np.allclose(data2, data2_)
# True

从上面我们可以看出,原始的data2和使用估计参数应用仿射变换得到的data2_几乎相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-17
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    相关资源
    最近更新 更多