ICP算法将两个点云作为输入,并返回刚性变换(旋转矩阵R和平移向量T),以最佳对齐点云。
例子:
[R T] = icp (q, p, 10);
将p点与q点进行10次迭代对齐。
然后使用
R*p+repmat(T,1,长度(p));
该文件实现了点对点和点对平面以及一些其他功能,如外推,加权函数,边缘点拒绝等。
有关ICP算法和实现的变体的介绍性文本,请参阅http://www2.imm.dtu.dk/~jakw/publications/bscthesis.pdf
Hans Martin kker & Jakob Wilm—PET运动校正表面配准算法的评估
Jakob Wilm(2021)。迭代最近点(//www.tatmou.com/matlabcentral/fileexchange/27804-iterative-closest-point), MATLAB中央文件交换。检索。
感谢
对于那些对“q的值无效”有问题的人。它必须满足函数:@(x)isreal(x)&&size(x,1)==3。因为矩阵需要转置。作者将x, y, z值放置在Denavit-Hartenberg类型格式中,其中有三行一列分别表示x, y和z点位置。所以,如果你有一个n行3列的大矩阵,转置那些矩阵,用icp函数解出旋转和变换矩阵,然后转置回去。
非常感谢您与我们分享您的工作。我曾尝试使用ICP函数将一个由顶点和面组成的对象与另一个对象对齐,但出现以下错误:
使用icp时出错(第128行)
“q”的值无效。它必须满足以下函数:@(x)isreal(x)&&size(x,1)==3。
下面已经有关于它的帖子,没有答案。请问您对此有何评论?
难以置信的强健和快速!
最重要的是,它可以将两个点云与一个大的姿势差异对齐,这填补了维基百科所说的缺口,当两个点云靠近时应该应用ICP。
@rebeen hamad你解决了吗?
这是一块宝石。
我有以下问题,你能帮我吗?
inputParser类没有适当的方法、属性或字段addParameter。
点云中的错误(第166行)
p.addParameter('Label', 'noLabel', @(x) ischar(x) || is空(x));
@liu yenfeng:嗨,你解决问题了吗?我也有同样的问题,如果方便的话,你能告诉我你是怎么解决的吗?
我正在寻找ICP来校准我的2D数据,你能帮我吗
非常感谢你的代码!
我有一个问题:
是否有人修改了eq_lmpoint()函数,以便lsqcurvefit函数在用户定义的误差度量上工作,以达到最小化?
我正在尝试改变误差度量,这使我的应用程序最小化,我找不到方法!
请问这段代码是用来纠正3d faces的pose变化的吗
谢谢你的努力,
但是我有一些问题:
如果我的数据是我模型的一部分(例如:模型=整个苹果数据=>半个苹果)
结果是失败,均方根是7.5,太高了
谁能告诉我怎么解决
您忘记在您的icp中包含'rmat2quat'函数。m文件。
干得好,谢谢你的努力。在我的例子中,它使用icp返回一个错误“error”(第128行)
“q”的值无效。它必须满足以下函数:@(x)isreal(x)&&size(x,1)==3。", which I can't figure out why it happens.
如有任何帮助,我将不胜感激。
非常感谢
不错的亚亚勒
好。谢谢
谢谢…我在找这个。。
你好,
我需要一些帮助,使我能够应用二维的ICP算法,而不是三维的ok。
Matlab上的代码非常复杂。我想用icp算法来匹配两个采样时间的数据。
最好的问候,
亚瑟
多谢! !
有没有可能限制你的算法只在重力方向上估计旋转,如果可能的话,你能告诉我怎么做吗?
雅各布,做得很好。我正在尝试注册心脏,它有内外表面,我有能力确定哪个节点对应哪个表面。是否有可能使用这个信息来明确设置哪些表面应该紧密匹配?或者你知道更好的方法吗?
它不接受k=0, ER(1)是我想要的吗?非常感谢你的支持。金宝app谢谢!
k=0(没有迭代)?因为我不想要任何配准,我只想要两个输入云点的RMS !
最近点通信的RMS可能是一个合适的测量。你从第三次输出的函数中得到它。
嗨,Jakob,我有一个三维点云形式的目标曲面,我必须不断地估计这个曲面(点云),然后将估计的曲面与目标曲面进行比较,看看我的新估计有多好。我只是在寻找一个度量来比较点云形式中的曲面,您的mfile是否返回这样一个度量?或者我可以用它来得到我想要的?
它非常适合我的3D数据点拟合:)谢谢
非常好的代码和论文链接!工作与我的数据,以及这个实现://www.tatmou.com/matlabcentral/fileexchange/24301-finite-iterative-closest-point
优秀的工作和详细的描述和支持的PDF使它如此好....金宝app
非常好的描述性函数。错误图是锦上添花!
这就跟你问声好!雅克布。当我尝试参数“weight”并给出一个1xn权重向量时,它的响应是:w不是一个'function_handle'。我必须在这里提供一个权函数,这样做对吗?或者一个权向量就足够了。
顺便说一句,优秀的代码!非常感谢!很鼓舞人心!
的问候!
黑雁。
我不知道为什么我不能预览这个内容类型。
对我的申请很有帮助。
你能告诉我旋转的顺序吗?是R(z)*R(y)*R(x)* P吗?
好了,问题解决了。
谢谢
雅各布,谢谢你在这么短的时间内给出的答复。
我发现在我的学习案例中kD-tree可能是最好的选择。
我实际上是在检查算法在我的云上是如何工作的:有没有一种方法来可视化算法选择的点作为两个云上对应的点?
谢谢你!
@ NS:直接这是不可能的。目前已经解决了正交Procrustes问题,因此每次迭代都有一个6DOF变换。如果你有约束条件下的解析解,你可以代入它,或者使用lm优化,它可以让你很自由地表达误差函数。
这在一定程度上取决于你对速度的定义。kD-tree很好,可以产生与brute force搜索相同的确定性输出。点到平面在每次迭代中花费更多一点,但是可以产生更快的收敛,因此速度更快。这要视情况而定,我建议你对数据进行计时。
哪些选项是推荐的最大速度的算法?
谢谢你!
嘿,雅各布,之前有人问过类似的问题,但我想再问一遍。有没有可能把你的icp算法限制为只翻译,也限制为只在特定方向翻译?问候,N。年代
嗨,Jakob,我试图通过改变匹配方法来改进我的结果,如“kd树”,“Delaunay”,“蛮力”。但这并没有改变我的结果。您能告诉我是什么原因吗?问候,Nazila
嗨jakob…我只是想知道你的这个ICP算法的函数调用。你能以两个3D矩阵数据或图像为例,说明我们需要调用这个ICP函数吗?我非常需要它。所以请帮帮我吧!!..
我尝试用两个CT扫描图像调用这个函数。但是我在函数调用中遇到了很多问题。
请帮帮我。
谢谢jakob ! !
这个实现是为3D数据编写和测试的。也就是说,您可以通过将所有z坐标设置为1来成功。
有办法把它用在二维数据上吗?
这正是我想要的!完美!
我在这里发现了实现://www.tatmou.com/matlabcentral/fileexchange/24301-finite-iterative-closest-point执行得更好。
仅适用于模拟数据。真实的数据已经需要很高的重叠了。方法不像它应该的那样工作,它更像迭代最重叠算法而不是关闭点。
这似乎是可行的,但只有在模型和数据相似的情况下。我有一个物体AB (3D),由A和b组成。我使用AB作为模型,使用A作为数据,但在这种情况下,为了适应AB, A变得两倍大?
这似乎是可行的,但只有在模型和数据相似的情况下。我有一个物体AB (3D),由A和b组成。我使用AB作为模型,使用A作为数据,但在这种情况下,为了适应AB, A变得两倍大?
这似乎是可行的,但只有在模型和数据相似的情况下。我有一个物体AB (3D),由A和b组成。我使用AB作为模型,使用A作为数据,但在这种情况下,为了适应AB, A变得两倍大?
@Tomasz:谢谢你的评论!我已经更新了你修改的功能我同意你的观点,这是一个很好的方法来确保一个合理的旋转矩阵!
嗨,雅各布和汉斯,
我喜欢使用您的代码,但对于我正在开发的某个应用程序,我提取了icp内的eq_point函数。并发现了可能存在的问题。
在某些情况下,返回的旋转矩阵是det(R)==-1,对于我的应用程序来说,这是一个问题。我知道,在许多真实的数据集中,这可能永远不会出现,但修复似乎很容易。
已经注意到,用于根据对应关系进行[R,T]估计的基于闭式SVD的解决方案有时可能会有问题。
您可以查看以下来自梅山的经典论文:
http://www.stanford.edu/class/cs273/refs/umeyama.pdf
我的解决方案是在eq_点的线上进行更改,以执行以下操作:
R=V*diag([11 det(U*V')])*U';
我没有彻底测试这个,但它似乎为我解决了问题。
干杯,黑客入侵快乐,
托马斯博士Malisiewicz
麻省理工学院CSAIL博士后研究学者
啊,p和q是(3 × m)和(3 × n).我的数据集是(m × 3).认为这是有序的。但现在我得到了另一个错误:我用‘dummy’替换了所有的波浪线,但似乎有一个被零错误除法。现在我得到了这样的回应:
???使用==> svd时出错
SVD的输入不能包含NaN或Inf。
345处==>icp>eq_点错误
[U,假,V] =圣言(N);奇异值分解%
错误在==> icp在231
[R,T]=eq_点(q(:,q_idx),pt(:,p_idx),权重(p_idx));
我在这里做什么?我要注册真正的3D点云。再次感谢您的代码和帮助
你的代码对我来说非常有用!(事实证明,随机噪声的添加导致了我最初的问题)。然而,它似乎只有在匹配接近时才会工作得很好——它是否有地方输入初始猜测以便更好地工作?
@Mark Brophy:
非常感谢你指出这一点。我发现kNearestNeighbors完全缺失,而kNN搜索只支持Stat. Toolbox v. 7.5或更高版本。金宝app
我添加了缺少的子函数并更新了代码,该代码将在24小时内可用。
/ Jakob
@彼得罗·帕拉:
我想你可能把准确性错当成了稳健性。
你基本上是在尝试注册平面,几乎没有机会与你的数据汇合。
试一试:
z(x,y)=50*exp(-(x-25.0)。^2./400.0-(y-25.0)。^2./400.0);
/ Jakob
@Jaden:
我相信算法中的一切都是确定的。然而,我不知道Mathwork的kD-tree实现的细节,可能会有一些模糊。
你没有显示你运行的代码,所以我没有机会告诉你到底哪里出了问题。
同样的结果与'Matching' == 'bruteForce' ?
/ Jakob
Jakob,当您在不使用统计数据包7.3版的情况下运行icp,同时使用“平面”选项时,它会在法线的计算中爆炸。
似乎stats包返回knn的格式与kNearestNeighbors方法不同。
使用==>减号时出错
矩阵维数必须一致。
Error in ==> icp>lsqnormest at 547
P=(x-repmat(P_-bar,1,k))*
置(x -
repmat (p_bar 1 k));%社民党矩阵
P
错误在==> icp在160
参数法线=lsqnormest(q,4);
你好,ICP代码似乎是伟大的工作,即使2 d输入,除了我继续这个错误当我运行一个循环中的ICP代码(它不会发生在同一迭代循环的每次,有时86,102,106,107,109,甚至更多)即使有相同的变量和设置和数据。
错误代码:
???使用==> KDTreeSearcher时出错。复杂数据是不允许的。
Error in ==> icp>match_kDtree at 335 [match mindist] = knnsearch(kdOBJ,转置(p));
Error in ==> icp at 289 [~, mindist] = match_kDtree(q,pt,kdOBJ);
Error in ==> testing_icp_movie at 37 [Ricp Ticp ER t] = icp(M, D, 50,'Matching', 'kDtree', 'Extrapolation',true);
在39次测试时出现==>总体编程错误2;
什么好主意吗?谢谢你!
我试着在已知的点分布上测试这个例程的准确性:模型点是高斯函数的[x y z]坐标;数据点是通过T变换模型点的(x,y)坐标得到的(data = model + repmat([1.5 1.5 0], size(model,1), 1))。即使T值很小,程序也不能收敛到最优。下面是用于测试的代码:
k = 0;
x = 1:50
对于y=1:50
Z (x,y) = exp(-(single(x) -25.0))^ 2。/ 400.0 - -25.0(单(y))。^ 2。/ 400.0);
k = k + 1;
模型(k,:) = [x y z (x, y)];
终止
终止
冲浪(双((1:50)),双((1:50)),双(z));
数据= model + repmat([15.5 15.5 0], size(model,1), 1);
[TR, TT, ER] = icp(double(model'), double(data'), 20)
任何建议吗?谢谢
戈兰:确保文件在Matlab路径中。Matlab 2007a/b应该工作。
嗨,雅各布,每次我想跑的时候——
[Ricp Ticp ER t]=icp(M,D,15);
我得到一个错误:??未定义函数或方法'icp'的输入参数类型为'double'。
你能告诉我是什么问题吗,我有2007年的matlab,也许icp函数在我的例子中不存在??
inp, DT, kdOBJ等都是范围管理的,所以没有内存泄漏。
嗨,雅各布,你的代码非常有用。
顺便说一下,我注意到两次内存泄漏。
一个是在GlTree的实现中,我将在该文件交换中发布。另一个是inputParser的使用。您应该清除inp中的对象。
嗨,塞巴斯蒂安,
谢谢你让我知道。我已经更正了链接,并将尽快重新添加rmat2quat函数。它将通过Mathworks审查,并将于明天提供。
为了将ICP限制到特定的自由度,我不认为有一个封闭形式的解决Procrustes问题的方法,但你应该检查文献。
我的想法是,你要么修改eq_point()或eq_plane(),并在估计后从R和T中删除'不需要的' DOF(这有点hackish)。或者您可以使用eq_lmpoint(),它对参数执行非线性优化,因此您基本上可以对那里的任何东西建模(这可能很慢)。
或者,你可以将整个拟合过程提出一个非线性优化问题,这实际上可以与ICP竞争。安德鲁·w·菲茨吉本。二维和三维点集的鲁棒配准。图像与视觉,21(13-14):1145-1153,2003。
问候,
雅克布
你好,雅克布,
因为您的ICP实现在最近的MATLAB摘要- Mai 2012时事通讯中有特别介绍,所以我重新访问了它,看看是否有更新可用。我注意到在你的新版本中,你忘记在你的icp中包含'rmat2quat'函数。m文件。如果在演示中启用Extrapolation,就可以重现错误。M文件,例如第57行。
对于我目前的工作,我想集成一些额外的约束,如Joachims在2012年2月20日的评论中提到的。您认为在您的框架中这是可能的吗?
来自德国的问候
塞巴斯蒂安。
附注:在描述的介绍性文字的链接是坏的(页面没有被DTU找到)。
你好Mithun,
缩放不需要解决,只需要平移和旋转(6自由度刚性变换)。
当做
该算法是否包含缩放ICP?
你好,雅克布,
非常好的工作。非常感谢。
我有一些特殊的边界条件在这里,我不确定如何实现和适合你的代码。
我需要在颅内压治疗期间调整一定的自由度。作为一个例子,我想让结果是只在X/Y方向平移和围绕z轴旋转。
您或其他人是否知道如何轻松地将此类功能集成到代码中?
提前谢谢!
愿一切都好!
约阿希姆
非常感谢-这非常有帮助。亲切的问候。
你好ucd宫殿,
在你的情况下,Matlab抱怨以下行(226在icpm):
[~, idx] = sort(mindist);
这可能是因为旧版本的Matlab不理解tilde(~)作为丢弃某个输出变量的方法。您可以更新到较新版本的Matlab,也可以使用虚拟输出(您必须在代码中的多个位置执行此操作),例如:
[dummy, idx] = sort(mindist);
问候,
雅克布
嗨,雅克布
当我运行演示文件时,我得到以下错误。任何建议。多谢。
------------------------------
??? 错误:文件:icp.m行:226列:11
表达式或语句不正确——可能是不平衡的(、{或[。
演示中出现错误==>57
[Ricp Ticp ER t]=icp(M,D,15);
-------------------------------------
很快就发表了评论。论证检查似乎没问题。它与其余的代码是一致的。
很抱歉造成了混乱
在函数参数解析中似乎存在一个小错误。线:
inp.addParamValue('Normals',[],@(x)isreal(x)和&size(x,1)==3);
似乎检查维度不同于帮助说明。
不应该读:
输入。addParamValue(法线,[],@ (x)伊斯雷尔(x) & & (x, 2)大小= = 3;
它可以用于二维点集配准吗?它引发了请求3D数据的错误消息。
嗨,雅各布,
演示。m是非常有用的,但它没有告诉我如何使用其他设置(法线,重量,三角…)。你能再给我看一些样本代码吗?
谢谢你的伟大工作。
你好,雅克布,
我看过不同的Matlab icp -包,你的是最快和最灵活的到目前为止。我只是想指出一点错别字。
在文档[第50行]中,你写:最小化{point} |平面| lmpoint
但是在代码[第123行]中,你检查:validMinimize = {'point','plane','lma_point'};
谢谢你的包裹。
对于kDtree匹配,统计工具箱v。需要7.3。
嗨,Jakob Wilm
代码包非常好!但错过KDTreeSearcher.m。
你能更新一下吗?
谢谢你的关注。现在已添加缺少的函数(rms_error.m)。
我也得到了米歇尔(2010年7月30日)提到的类似错误。这将是有益的,如果这是固定的。
看起来很好,但我没有icp。因为我认为它缺少rms_error函数。我做错什么了吗?