gpt4 book ai didi

java - 如何解释迭代最近点 (ICP) 算法的距离

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:37:04 26 4
gpt4 key购买 nike

我正在尝试开发一个应用程序,它使用 ICP 算法来查找在特定区域中绘制的形状之间的相似性,但我不明白如何解释我在它结束时得到的距离。这是我使用的算法,仅从点列表开始:enter image description here其中 w 是旋转角度,T=(Tx, Ty) 是平移 vector 。它们也被描述为:enter image description here
其中:enter image description here现在,我尝试绘制几个形状,但我异常(exception)的是,如果形状非常相似,结果将接近 0。相反,通过这些形状,我得到了 3515.334 的最终值:enter image description here
有了这个,我得到了6615.08:enter image description here
最后,有了这个(它们完全不同)我得到了454.54:enter image description here
我是不是理解错了算法?这是实现:

   private void icp (int z, ArrayList<Pair<Float,Float>> points) {
ArrayList<Pair<Float,Float>> copia = segments.get(z);
ArrayList<Pair<Float,Float>> copia2 = points;
double x_trattino = 0.0;
double y_trattino = 0.0;
double x_trattino_primo = 0.0;
double y_trattino_primo = 0.0;
for (int i=0; i<copia.size(); i++) {
x_trattino+=copia.get(i).first;
y_trattino+=copia.get(i).second;
}
x_trattino = x_trattino*((double)1/copia.size());
y_trattino = y_trattino*((double)1/copia.size());
for (int i=0; i<copia2.size(); i++) {
x_trattino_primo+=copia2.get(i).first;
y_trattino_primo+=copia2.get(i).second;
}
x_trattino_primo = x_trattino_primo*((double)1/copia2.size());
y_trattino_primo = y_trattino_primo*((double)1/copia2.size());
double Sxx = 0.0;
double Syy = 0.0;
double Sxy = 0.0;
double Syx = 0.0;
int min = 0;
if (copia.size()>copia2.size()) min = copia2.size(); else min = copia.size();
for (int i=0; i<min; i++) {
Sxx+=((copia.get(i).first-x_trattino)*(copia2.get(i).first-x_trattino_primo));
}
for (int i=0; i<min; i++) {
Syy+=((copia.get(i).second-y_trattino)*(copia2.get(i).second-y_trattino_primo));
}
for (int i=0; i<min; i++) {
Sxy+=((copia.get(i).first-x_trattino)*(copia2.get(i).second-y_trattino_primo));
}
for (int i=0; i<min; i++) {
Syx+=((copia.get(i).second-y_trattino)*(copia2.get(i).first-x_trattino_primo));
}
double rotation = Math.toDegrees(Math.atan((Sxy-Syx)/(Sxx+Syy)));

double Tx = x_trattino_primo - (x_trattino*Math.cos(rotation)-y_trattino*Math.sin(rotation));
double Ty = y_trattino_primo - (x_trattino*Math.sin(rotation)+y_trattino*Math.cos(rotation));
double eDist = 0.0;

for (int i=0; i<min; i++) {
eDist = (Math.pow(copia.get(i).first*Math.cos(rotation)-copia.get(i).second*Math.sin(rotation)+Tx-copia2.get(i).first, 2.0)+Math.pow(copia.get(i).first*Math.sin(rotation)+copia.get(i).second*Math.cos(rotation)+Ty-copia2.get(i).second, 2.0));
}

System.out.println("EDIST: "+eDist);
}

最佳答案

你犯过的错误

  1. 不要使用 Math.toDegrees,完全跳过该调用,变量 rotation 中的值应该以弧度而不是度为单位。
  2. 你写的是“eDist = ...”而不是“eDist += ...”。
  3. 您假设某些“定义点”应该在两个不同的形状中匹配。这可能是代码中最大的问题之一。假设您有两条线,第一条分为两部分,而另一条则不是。像这样

    .--------.---------.
    .------------------.

    你要比较的是形状

    .--------.
    .------------------.

    这两个形状不会相似,因此不会给出很小的距离。这意味着您可以拥有两个看起来非常相似的形状,但您的算法不会检测到这一点。举一个更复杂的例子来说明您要匹配的内容是,如果您在两个形状中有几个像这样的点

    p1--p2--p3----p4----------p5---p6
    q1------q2----------------q3---q4

    您要匹配的是 p1 到 q1、p2 到 q2、p3 到 q3 和 p4 到 q4。这显然不能令人满意。

一个前进的方向

选择一个形状作为源,另一个作为目标。对于每个源点,找到目标中最近的点。现在你有一对点,它们是你应该在公式中使用的匹配点 P 和 P'。请注意,源中的多个点可以与目标中的同一点配对。重复这个过程,直到误差距离没有足够的改善。

还有其他处理 ICP 的方法,并且可能会出现几个问题。需要指出的一个问题是,如果你在我给你的直线示例中使用上述方法,误差距离可能不会变小,因为中点不靠近另一个形状中的任何点。所以上面的建议并没有穷尽所有可以做的事情,但至少我已经给了你一个开始。

关于java - 如何解释迭代最近点 (ICP) 算法的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57513196/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com