我试图适应从一组坐标到另一组坐标的转换。

x' = R + Px + Qy
y' = S - Qx + Py
Where P,Q,R,S are constants, P = scale*cos(rotation). Q=scale*sin(rotation)

存在用于将P,Q,R,S拟合到一组对应点的“手动”公式。 但我需要对拟合进行误差估计 - 所以我需要一个最小二乘解。

阅读'数字食谱',但我无法解决如何对其中包含x和y的数据集进行此操作。

任何人都可以指向如何执行此操作的示例/教程/代码示例?
对语言不太感兴趣。
但是 - 只是使用Matlab / Lapack / numpy / R的内置功能可能没有帮助!

编辑:我有一大套旧(x,y)新(x,y)适合。 问题是超定的(比未知数更多的数据点)如此简单的矩阵求逆是不够的 - 正如我所说,我真的需要拟合上的误差。

#1楼 票数:4

要查找P,Q,R和S,您可以使用最小二乘法。 我认为令人困惑的是,通常的最小二乘描述使用x和y,但它们与你问题中的x和y不匹配。 您只需要将问题小心地转换为最小二乘框架。 在你的情况下,自变量是未转换的坐标x和y,因变量是变换后的坐标x'和y',可调参数是P,Q,R和S.(如果这个不够清楚,让我知道,我会发布更多细节。)

一旦找到P,Q,R和S,然后scale = sqrt(P ^ 2 + Q ^ 2),然后您就可以从sin rotation = Q / scale和cos rotation = P / scale找到旋转。

#2楼 票数:4 已采纳

以下代码应该可以解决问题。 我使用以下公式来表示残差:

residual[i] =   (computed_x[i] - actual_x[i])^2
              + (computed_y[i] - actual_y[i])^2

然后根据Wolfram的MathWorld中描述的一般程序推导出最小二乘公式。

我在Excel中测试了这个算法并且它按预期执行。 我使用了十个随机点的集合,然后通过随机生成的变换矩阵进行旋转,平移和缩放。

由于没有随机噪声施加到输出数据,该程序产生四个参数( PQRS ),它们与输入参数相同,并且rSquared值为零。

随着越来越多的随机噪声应用于输出点,常数开始偏离正确的值,并且rSquared值相应地增加。

这是代码:

// test data
const int N = 1000;
float oldPoints_x[N] = { ... };
float oldPoints_y[N] = { ... };
float newPoints_x[N] = { ... };
float newPoints_y[N] = { ... };

// compute various sums and sums of products
// across the entire set of test data
float Ex =  Sum(oldPoints_x, N);
float Ey =  Sum(oldPoints_y, N);
float Exn = Sum(newPoints_x, N);
float Eyn = Sum(newPoints_y, N);
float Ex2 = SumProduct(oldPoints_x, oldPoints_x, N);
float Ey2 = SumProduct(oldPoints_y, oldPoints_y, N);
float Exxn = SumProduct(oldPoints_x, newPoints_x, N);
float Exyn = SumProduct(oldPoints_x, newPoints_y, N);
float Eyxn = SumProduct(oldPoints_y, newPoints_x, N);
float Eyyn = SumProduct(oldPoints_y, newPoints_y, N);

// compute the transformation constants
// using least-squares regression
float divisor = Ex*Ex + Ey*Ey - N*(Ex2 + Ey2);
float P = (Exn*Ex + Eyn*Ey - N*(Exxn + Eyyn))/divisor;
float Q = (Exn*Ey + Eyn*Ex + N*(Exyn - Eyxn))/divisor;
float R = (Exn - P*Ex - Q*Ey)/N;
float S = (Eyn - P*Ey + Q*Ex)/N;

// compute the rSquared error value
// low values represent a good fit
float rSquared = 0;
float x;
float y;
for (int i = 0; i < N; i++)
{
    x = R + P*oldPoints_x[i] + Q*oldPoints_y[i];
    y = S - Q*oldPoints_x[i] + P*oldPoints_y[i];
    rSquared += (x - newPoints_x[i])^2;
    rSquared += (y - newPoints_y[i])^2;
}

#3楼 票数:1

定义3×3矩阵T(P,Q,R,S),使得(x',y',1) = T (x,y,1) 然后计算

A = \sum_i |(T (x_i,y_i,1)) - (x'_i,y'_i,1)|^2

并最小化A(P,Q,R,S)。

自己编码是一个中型到大型项目,除非你能保证数据条件良好,特别是当你想要从程序中获得良好的错误估计时。 你可能最好使用支持误差估计的现有最小化器。

粒子物理类型将直接从CERNLIB使用minuit (编码最容易在fortran77中完成),或者从ROOT (使用c ++编码,或者它应该可以通过python绑定访问)。 但如果您还没有这些工具,那么这是一个很大的安装。

我相信其他人可以建议其他最小化器。

#4楼 票数:1

您可以使用levmar程序来计算它。 它经过测试并集成到包括我的多种产品中。 它是根据GPL许可的,但如果这是一个非开源项目,他将为您更改许可证(收费)

#5楼 票数:1

谢谢eJames,这几乎是我所拥有的。 我用一本旧的军队测量手册编写了这本书,该手册是基于早先的“测量员指南”说明,必须是100岁! (它使用北和东的N和E而不是x / y)

拟合优度参数将非常有用 - 如果它们使拟合更糟,我可以交互式地抛出选定的点。

FindTransformation(vector<Point2D> known,vector<Point2D> unknown) {
{
    // sums
    for (unsigned int ii=0;ii<known.size();ii++) {
       sum_e += unknown[ii].x;
       sum_n += unknown[ii].y;
       sum_E += known[ii].x;
       sum_N += known[ii].y;                            
       ++n;         
    }

    // mean position
    me = sum_e/(double)n;
    mn = sum_n/(double)n;
    mE = sum_E/(double)n;
    mN = sum_N/(double)n;

    // differences
    for (unsigned int ii=0;ii<known.size();ii++) {

       de = unknown[ii].x - me;
       dn = unknown[ii].y - mn;

       // for P
       sum_deE += (de*known[ii].x);
       sum_dnN += (dn*known[ii].y);
       sum_dee += (de*unknown[ii].x);
       sum_dnn += (dn*unknown[ii].y);

       // for Q
       sum_dnE += (dn*known[ii].x);
       sum_deN += (de*known[ii].y);                     
   }

double P = (sum_deE + sum_dnN) / (sum_dee + sum_dnn);
double Q = (sum_dnE - sum_deN) / (sum_dee + sum_dnn);

double R = mE - (P*me) - (Q*mn);
double S = mN + (Q*me) - (P*mn);
}

#6楼 票数:0

一个问题是像这样的数字通常是棘手的。 即使算法很简单,实际计算中也经常会出现问题。

因此,如果有一个系统可以轻松获得具有内置功能的系统,那么最好使用它。

  ask by Martin Beckett translate from so

未解决问题?本站智能推荐:

1回复

在n个变量中查找单个线性方程的解,或者确定不存在解

假设您有n个变量的线性方程。 我们的目标是要么确定没有整数解是可能的,或确定最小系数矢量, 对于一个整数解 。 换句话说,让ax=b ,其中x是您要查找的向量,而a是系数的向量。 b是标量常数。 找到x使得x1, ... ,xn的总和最小化,并且所有xi都是整数。 或者,确定不存在这
2回复

什么是在3个未知变量上找到N个多项式方程组的数值解的快速算法?

我正在寻找一种快速算法来解决3个未知变量的N个多项式方程组。 也就是说,给定3个函数, F0(x,y,z), F1(x,y,z)... FN(x,y,z) ,我想找到x, y, z ,使得F0(x,y,z) = F1(x,y,z) = ... = FN(x,y,z) = 0 。 我试过在几
6回复

最小化一个函数

假设给定一个由单个变量和参数 a 和 b 组成的函数,并要求您找出该函数在区间 [a, b] 上的最小值。 (您可以假设参数是双精度值,但在我的应用程序中,我可能需要使用任意精度的库。) 一般来说,这是一个难题,因为函数可能很奇怪。 这个问题的一个简单版本是假设函数是连续的(没有间隙或跳跃)和单峰
7回复

最小面积四边形算法

有一些算法可以用于查找包含给定(凸)多边形的最小边界矩形。 有人知道寻找最小面积四边形(任何四边形,而不仅仅是矩形)的算法吗? 我已经在互联网上搜索了几个小时,但是虽然我找到了一些关于这个问题的理论论文,但我没有找到一个实现...... 编辑:Mathoverflow 的人向我指出了一篇带有数学解决
1回复

如何生成浮点数的随机分区,并且每个部分的最小值为pMin?

例如: 我想将33.38分为5个部分,每个部分等于或大于1.2: 2.71,3.3,18.7,1.56,7.11 伪代码中的功能: 另一种情况: 将18.77分为3部分,每部分等于或大于3.2: 4.8,9.55,4.42 当然,输入和输出可能是丑陋的浮点数,例如3.
1回复

一维箱式装箱问题的MBS算法(最小箱装松弛)

我正在努力解决一维箱装箱问题,并且作为初始种群,我将从MBS的发生器颗粒开始。 我在网上寻找MBS(最小bin松弛)算法,但找不到。 有人可以帮我吗?
3回复

找到最小比例因子,从一组双打中得到每个数字在整数的十分之一内

假设我们有一组双打S,这样的事情: 我们现在想要找到最小的正整数比例因子x ,其中s的任何元素乘以x都在整数的十分之一之内。 对不起,如果不是很清楚 - 请在需要时请求澄清。 请限制C风格语言或算法伪代码的答案。 谢谢!
1回复

通过重复删除第一个和中间、第一个和最后一个或中间和最后一个元素来清空数组的最小成本

这个问题是在一次采访中问到我的,我无法想出一个最佳的解决方案。 问题 给定一个偶数大小的数组,我们可以对数组执行任何操作,直到数组变空,这样总成本应该是最小的。 操作: 删除第一个和最后一个元素 => 成本将是gcd(first, last) 删除第一个和中间元素 => 成本