【问题标题】:Estimate Euclidean transformation with python用python估计欧几里得变换
【发布时间】:2026-01-13 14:15:02
【问题描述】:

我想做一些类似于图像分析中使用特征的标准“图像配准”的事情。

我想找到将一组 2D 坐标 A 转换为另一个 B 的最佳转换。 但我想添加一个额外的约束,即变换是“刚性/欧几里得变换”,这意味着没有缩放,只有平移和旋转。 通常允许缩放我会这样做:

 from skimage import io, transform
 destination = array([[1.0,2.0],[1.0,4.0],[3.0,3.0],[3.0,7.0]])
 source = array([[1.2,1.7],[1.1,3.8],[3.1,3.4],[2.6,7.0]])
 T = transform.estimate_transform('similarity',source,destination)

我相信estimate_transform 在幕后只是解决了最小二乘问题。 但是我想添加不缩放的约束。

skimage 或其他软件包中是否有任何功能可以解决此问题? 可能我需要用 scipy、CVXOPT 或 cvxpy 编写自己的优化问题。 对表述/实施这个优化问题有什么帮助吗?

编辑: 感谢 Stefan van der Walt Answer

from matplotlib.pylab import *
from scipy.optimize import *

def obj_fun(pars,x,src):
    theta, tx, ty = pars
    H = array([[cos(theta), -sin(theta), tx],\
         [sin(theta), cos(theta), ty],
         [0,0,1]])
    src1 = c_[src,ones(src.shape[0])]
    return sum( (x - src1.dot(H.T)[:,:2])**2 )

def apply_transform(pars, src):
    theta, tx, ty = pars
    H = array([[cos(theta), -sin(theta), tx],\
         [sin(theta), cos(theta), ty],
         [0,0,1]])
    src1 = c_[src,ones(src.shape[0])]
    return src1.dot(H.T)[:,:2]

res = minimize(obj_fun,[0,0,0],args=(dst,src), method='Nelder-Mead')

【问题讨论】:

    标签: python image-processing scikit-image homogenous-transformation


    【解决方案1】:

    有了这个额外的约束,您将不再解决线性最小二乘问题,因此您必须使用 SciPy 的最小化函数之一。最小化的内部部分将建立一个矩阵 H:

    H = np.array([[np.cos(theta), -np.sin(theta), tx],
                  [np.sin(theta), np.cos(theta), ty],
                  [0, 0, 1]])
    

    然后,您将计算距离

    |x_target - H.dot(x_source)|
    

    对于所有数据点并对错误求和。现在,您有一个可以发送到最小化函数的成本函数。您可能还想使用 RANSAC(skimage.measure.ransac)来拒绝异常值。

    【讨论】:

    • 感谢您的回答我实现了它并且它有效。
    • 我遗漏了一些细节,例如齐次坐标等,所以很高兴让它如此轻松地工作!
    【解决方案2】:

    skimage 现在在转换模块中提供原生支持。

    http://scikit-image.org/docs/dev/api/skimage.transform.html#skimage.transform.estimate_transform

    比我发现的 OpenCV 容易一些。有一套广泛的功能,涵盖所有用例。

    【讨论】: