【发布时间】:2019-08-15 16:46:38
【问题描述】:
我正在尝试开发一个应用程序,该应用程序使用 ICP 算法来查找在特定区域绘制的形状之间的相似性,但我不明白如何解释我在它结束时得到的距离。这是我使用的算法,仅从点列表开始: 其中 w 是旋转角度,T=(Tx, Ty) 是平移向量。它们也被描述为:
在哪里: 现在,我尝试绘制几个形状,但我所例外的是,如果形状非常相似,结果将接近 0。相反,通过这些形状,我得到了最终值 3515.334:
有了这个我得到了 6615.08:
最后,有了这(它们完全不同)我得到 454.54:
我误解了算法吗?
这是实现:
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);
}
【问题讨论】:
-
您可以使用算法的开源实现来检查您的输出。看起来您的距离测量部分是原始点数的函数(通常,点越多,距离越大)。这似乎不是直接的相似性度量。
-
@JohnColeman 我所做的是将算法转换为代码,但我不明白它是否在检查形状之间的相似性。我可以想象看到结果是:最终结果越大,形状越相似。你对此有什么看法?
-
你确定这是ICP吗?这里似乎没有任何最近点的迭代:您只是假设两个形状的第 i 个点之间的对应关系,然后将它们对齐一次。您不应该搜索最近的点,而不是假设对应关系是先验正确的吗?
-
@AndyTurner 我发现该算法用于检查两个形状的相似程度。我错了吗?
-
@Fabio 你在这里所做的是Procrustes analysis,而不是 ICP(具体来说,是没有缩放的正交 Procrustes)。
标签: java android algorithm math coordinates