基于ICP算法的图像配准的MATLAB实现
ICP算法在叶型点云数据配准中的应用

ICP算法在叶型点云数据配准中的应用刘峻峰;何小妹;黄翔;王一璋【摘要】针对叶片截面型线测量点云数据与理论点云数据的配准问题,研究了将ICP算法应用于叶型点云数据配准的方法.首先概述了叶型测量数据与理论数据的匹配问题;然后阐述了基于ICP算法的叶型点云数据配准方法,并在MATLAB平台进行了配准实现;最后给出了配准实例,并将配准结果与点云处理软件CloudCompare的匹配结果进行了对比,验证了该方法的准确性.【期刊名称】《航空制造技术》【年(卷),期】2019(062)012【总页数】4页(P79-82)【关键词】叶片;截面型线;ICP算法;配准;刚体变换【作者】刘峻峰;何小妹;黄翔;王一璋【作者单位】航空工业北京长城计量测试技术研究所,北京100095;南京航空航天大学机电学院,南京210016;航空工业北京长城计量测试技术研究所,北京100095;南京航空航天大学机电学院,南京210016;航空工业北京长城计量测试技术研究所,北京100095【正文语种】中文叶片是航空发动机的关键零部件,其设计和制造质量直接影响着发动机的性能。
目前,叶片制造质量主要采用标准样板法、自动绘图测量法、光学投影测量法、电感测量法和坐标测量法等手段进行评价[1],其中坐标测量法因其具有高精度的特点[2],在国内发动机主机厂得到了广泛应用。
图1为使用三坐标测量机对发动机叶片进行等高截面法测量的示意图,按照航空标准HB5647—98《叶片叶型的标准、公差与叶身表面粗糙度》的规定,首先沿叶片积叠轴的方向围绕各检验剖面进行测量,然后对叶型轮廓度、积叠点位置度、扭转等参数进行评价,做出合格性与否的判定。
其中在叶片截面测量和参数评价过程中,涉及到叶片测量坐标系与模型坐标系对齐以及叶片截面型线测量数据和理论数据匹配的问题,处理好这两个问题将会对上述叶片参数的评价起到关键作用。
图1 叶片等高截面法测量示意图Fig.1 Schematic diagram of blade isometric cross-section measurement目前关于坐标测量机坐标系建立方法的研究较多,如常用的“3-2-1”法、6点迭代法等,而关于叶片截面型线测量数据和理论数据匹配的问题,该环节为利用叶片参数专用评价商业软件对叶片参数进行评价的中间过程,关注较少,但该问题对后续叶片叶型轮廓度误差的评价具有关键作用。
图像配准matlab代码

registration.mclearclcimg = imread('.\image\test1.tif');figure(1)imshow(img)disp('获取原图像四个顶点在该图中的坐标'); impixelinfo%四个顶点的坐标x1 = 0;y1 = 0;x2 = 688;y2 = 200;x3 = 20;y3 = 688;x4 = 708;y4 = 888;rs = size(img);rows = rs(1); %行数columns = rs(2); % 列数%[rows , columns] = size(img);%获取原图的大小R = round(((y3-y1)+(y4-y2))./2); %行C = round(((x2-x1)+(x4-x3))./2); %列D1 = rows -R; %垂直偏移像素数D2 = columns -C; %水平偏移像素数img1 = zeros(R,C);for i = 1:Rd2 = round(D2*i./R);for j = 1:Cd1 = round(D1*j./C);img1(i,j) = floor(img(i+d1,j+d2));endendfigure(2)imshow(img1)imwrite(uint8(img1),strcat('.\image\','result.tif'),'tif');transform.mclearclc%读取图像img = imread('.\image\test.tif');figure(1)imshow(img)%计算出图像的大小rs = size(img);rows = rs(1); %行数columns = rs(2); % 列数%将图像水平偏移20个像素,垂直偏移200个像素img1 = zeros(rows+200,columns+20);for i = 1:rowsx = round(20 * i ./ rows);for j = 1:columnsy = round(200 * j ./columns);img1(i+y,j+x) = floor(img(i,j));endendimwrite(uint8(img1),strcat('.\image\','test1.tif'),'tif');figure(2)imshow(img1)WORK.mclearimg = imread('.\image\test1.tif');org = imread('.\image\test.tif');figure('name','原图')imshow(org)impixelinfofigure('name','偏移之后的图像')imshow(img)disp('获取原图像四个顶点在该图中的坐标'); impixelinfo[r,c] = size(org);u1 = 619;v1 = 150;u2 = 574;v2 = 605;u3 = 130;v3 = 234;u4 = 58;v4 = 538;x1 = 622;y1 = 329;x2 = 590;y2 = 773;x3 = 139;y3 = 275;x4 = 75;y4 = 557;A = [u1,v1,u1*v1,1,0,0,0,0;...0,0,0,0,u1,v1,u1*v1,1;...u2,v2,u2*v2,1,0,0,0,0;...0,0,0,0,u2,v2,u2*v2,1;...u3,v3,u3*v3,1,0,0,0,0;...0,0,0,0,u3,v3,u3*v3,1;...u4,v4,u4*v4,1,0,0,0,0;...0,0,0,0,u4,v4,u4*v4,1];B = [x1;y1;x2;y2;x3;y3;x4;y4];%C = [c1;c2;c3;c4;c5;c6;c7;c8];C = inv(A)*B;%[c1,c2,c3,c4,c5,c6,c7,c8] = C;c1 = C(1,1);c2 = C(2,1);c3 = C(3,1);c4 = C(4,1);c5 = C(5,1);c6 = C(6,1);c7 = C(7,1);c8 = C(8,1);I = zeros(r,c);[rr,cc] = size(img);for i =1:rfor j = 1:cx = round(c1*i+c2*j+c3*i*j+c4);y = round(c5*i+c6*j+c7*i*j+c8);if x>rrx = rr;endif y>ccy = cc;endI(i,j) = img(x,y);endendfigure('name','Result')imshow(uint8(I))。
MATLAB中的图像配准与形变分析技术

MATLAB中的图像配准与形变分析技术一、引言图像处理是计算机科学中重要的研究领域之一,图像配准与形变分析技术是图像处理中的一个重要分支。
在现代科技和医学领域,图像配准和形变分析技术的应用非常广泛。
本文将介绍MATLAB中的图像配准与形变分析技术的原理、方法和应用。
二、图像配准的原理与方法图像配准是指将两幅或多幅图像对齐,使其在空间上一一对应。
在MATLAB 中,实现图像配准有多种方法,常用的方法包括灰度匹配、特征点匹配和基于变换模型的配准。
1. 灰度匹配灰度匹配是将两幅图像的像素值进行调整,使它们的直方图相似。
在MATLAB中,可以使用imhist和histeq函数实现灰度匹配。
imhist函数可以计算图像的直方图,而histeq函数可以对图像进行直方图均衡化,从而达到灰度匹配的效果。
2. 特征点匹配特征点匹配是一种常用的图像配准方法,它通过提取图像中的关键特征点,然后利用这些特征点进行图像对应的搜索与匹配。
在MATLAB中,可以使用SURF (速度加速稳健特征)算法或SIFT(尺度不变特征转换)算法来提取图像中的特征点。
通过特征点的匹配,可以得到两幅图像之间的对应关系,并进一步进行图像的配准。
3. 基于变换模型的配准基于变换模型的配准是一种基于几何变换的图像配准方法。
在MATLAB中,常用的变换模型有仿射变换、透视变换等。
仿射变换是一种线性变换,可以通过三个非共线的点对进行计算。
MATLAB提供了cp2tform函数,可以通过特征点匹配得到的对应关系计算出仿射变换矩阵,从而实现图像的配准。
透视变换是一种非线性变换,可以通过四个非共线的点对进行计算。
在MATLAB中,可以使用fitgeotrans函数计算出透视变换矩阵,并实现图像的配准。
三、形变分析的原理与方法形变分析是指对图像进行变形分析,研究形变的特点和规律。
在MATLAB中,可以使用变形场和形变图来表征形变信息。
1. 变形场在形变分析中,变形场是指描述变形大小和方向的向量场。
图像配准与匹配在MATLAB中的实现方法

图像配准与匹配在MATLAB中的实现方法引言图像配准与匹配是数字图像处理领域的重要研究方向,广泛应用于医学图像处理、遥感图像处理、计算机视觉等领域。
图像配准与匹配的目标是找到多幅图像之间的几何变换关系,使它们能够在相同的坐标系统下进行比较、融合或分析。
而MATLAB作为图像处理与分析的重要工具,提供了丰富的函数和工具箱,可以方便地实现图像配准与匹配。
一、图像配准与匹配的概念1. 图像配准图像配准是将多幅图像投影到同一坐标系统的过程。
其目标是找到一个几何变换关系,使得多幅图像在此变换下能够对齐,即各个像素点所代表的相同位置的物理含义保持一致。
图像配准可以分为刚性配准和非刚性配准。
刚性配准是指在图像进行配准过程中,只考虑平移、旋转和缩放三种刚性变换,并忽略了图像的非刚性变形。
非刚性配准则考虑了更加复杂的变换,例如弯曲、扭曲等。
2. 图像匹配图像匹配是指在完成配准后,进一步比较和分析图像之间的相似性。
图像匹配可以通过计算图像间的相似性度量指标,例如均方差、相关系数等,得出两幅图像的相似程度。
在医学图像中的应用广泛,例如针对同一患者不同时间点的影像图像,可用于疾病进展的监测和分析。
二、MATLAB中图像配准与匹配的实现方法1. 刚性变换配准MATLAB提供了一些函数,例如"imregtform"和"imregister"等,可以实现图像的刚性配准。
通过这些函数,我们可以选择适当的变换模型,例如平移、旋转和缩放,配准多幅图像。
以"imregister"函数为例,其使用方法如下:```movingRegistered = imregister(moving,fixed,transformType,optimizer,metric);```参数中,moving代表待配准的移动图像,fixed代表已经配准好的固定图像。
transformType表示选择的变换模型,optimizer和metric表示配准的优化器和评价指标。
MATLAB中的图像配准与匹配方法

MATLAB中的图像配准与匹配方法图像配准与匹配是计算机视觉领域的重要研究方向。
配准指的是将多幅图像在空间上对齐,使得它们之间的特定特征点或特征区域对应一致。
匹配则是在已经配准的图像中寻找相似的图像区域。
在实际应用中,图像配准与匹配常用于医学图像分析、遥感影像处理、计算机视觉等领域,具有广泛的应用前景。
MATLAB作为一种强大的数值计算与数据可视化软件,提供了丰富的图像处理和计算机视觉函数,使得图像配准与匹配任务变得更加简便和快捷。
下面将介绍几种常用的MATLAB图像配准与匹配方法。
一、基于特征点的图像配准特征点是图像中具有鲁棒性和独特性的点,常常用于图像配准任务。
在MATLAB中,可以使用SURF(Speeded-Up Robust Features)或SIFT(Scale-Invariant Feature Transform)等函数来检测图像中的特征点。
然后可以通过计算特征点间的相似度或使用一致性约束等方法来对图像进行配准。
二、基于图像区域的图像配准除了特征点外,图像的局部区域也可以作为配准的参考。
一种常用的方法是使用归一化互相关(Normalized Cross Correlation)来度量两幅图像之间的匹配度。
在MATLAB中,可以使用normxcorr2函数来实现归一化互相关操作。
该函数将两幅图像进行归一化,并计算它们之间的互相关系数,从而确定最佳的配准位置。
三、基于形态学的图像配准形态学图像处理是一种基于形态学运算的图像处理方法。
它利用图像中的形状、结构和拓扑信息来进行图像处理和分析。
在图像配准中,形态学操作可以用来提取图像区域的形状信息,并进行形状匹配。
在MATLAB中,可以使用bwmorph函数进行形态学操作,例如腐蚀、膨胀、开运算、闭运算等,从而实现图像的配准与匹配。
四、基于变换模型的图像配准图像配准中常常涉及到图像的几何变换,例如平移、旋转、缩放、投影变换等。
在MATLAB中,可以使用imwarp函数来对图像进行几何变换和配准。
点云模型的优化配准方法研究

点云模型的优化配准方法研究一、引言点云模型是三维数字化技术中的一种重要形式,它具有高精度、高效率等优点,在工业制造、建筑设计、文物保护等领域得到广泛应用。
然而,由于采集设备和算法的局限性,点云模型在采集和处理过程中会出现噪声、缺失数据和误差等问题,因此需要对其进行优化配准。
本文将介绍点云模型的优化配准方法研究。
二、点云模型的基本概念1. 点云模型是由大量三维坐标点组成的数据集合,每个坐标点都有自己的位置和属性信息。
2. 点云模型可以通过激光扫描、摄影测量等方式获取。
3. 点云模型可以用于三维重建、形态分析、物体识别等领域。
三、点云模型的优化配准方法1. 基于特征匹配的方法特征匹配是一种常见的点云配准方法,其基本思想是在两个点云中提取出相同或相似的特征,并通过计算这些特征之间的距离来确定它们之间的对应关系。
特征匹配方法包括SIFT、SURF、ORB等。
2. 基于ICP算法的方法ICP(Iterative Closest Point)算法是一种迭代优化的点云配准算法,其基本思想是通过迭代计算两个点云之间的最小距离来优化它们之间的对应关系。
ICP算法包括ICP、ICP变形、快速ICP等。
3. 基于深度学习的方法深度学习技术在点云配准中也得到了广泛应用,其基本思想是通过神经网络学习两个点云之间的映射关系,并将其用于点云配准。
深度学习方法包括PointNet、PointNet++等。
四、实验结果与分析本文选取了SIFT特征匹配和ICP算法作为实验对象,采用MATLAB编程实现了点云模型的优化配准,并进行了实验验证。
实验结果表明,SIFT特征匹配和ICP算法都能够有效地提高点云模型的精度和稳定性,但在不同场景下表现略有差异。
五、结论与展望本文介绍了三种常见的点云模型优化配准方法,并通过实验验证了SIFT特征匹配和ICP算法的有效性。
未来,随着深度学习技术的不断发展,基于深度学习的点云配准方法将会得到更加广泛的应用。
Matlab中的图像配准与对齐方法
Matlab中的图像配准与对齐方法图像配准与对齐是数字图像处理中的重要步骤,能够将多幅图像对齐到同一坐标系,实现图像的比较、特征提取和分析。
Matlab作为一种强大的计算工具和编程语言,提供了多种图像配准与对齐方法的函数和工具箱,方便用户进行图像处理和分析。
本文将介绍Matlab中的一些常用的图像配准与对齐方法,包括特征点配准、基于亮度的配准和图像退化模型配准。
一、特征点配准特征点配准是一种常用的图像配准方法,通过在两幅图像中提取出一些具有显著特征的点,并将这些点匹配起来,从而实现图像的对准。
Matlab提供了SURF (Speeded Up Robust Features)算法和SIFT(Scale-Invariant Feature Transform)算法用于特征点的提取和匹配。
用户可以使用Matlab的Image Processing Toolbox中的相关函数,在两幅图像中提取出SURF或SIFT特征点,并使用Matlab的vision.PointTracker对象进行特征点的匹配和跟踪。
通过特征点的匹配,可以获取两幅图像之间的变换矩阵,进而实现图像的配准和对齐。
二、基于亮度的配准基于亮度的配准方法是一种利用图像亮度信息进行对齐的方法,其原理是通过优化亮度的判断标准,使两幅图像的亮度分布尽量一致,从而实现图像的对齐。
Matlab提供了基于亮度的配准算法,用户可以使用Matlab的imregcorr函数进行基于亮度的图像配准。
该函数可以计算两幅图像之间的亮度相关性,并找到亮度最大的对齐方式。
通过该算法,用户可以快速实现对齐图像的配准。
三、图像退化模型配准图像退化模型配准是一种利用具有退化模型的图像进行对齐的方法,其原理是先对待配准图像进行退化处理,再与目标图像进行比较,从而找到最佳的配准方式。
Matlab提供了图像退化模型配准的函数和工具箱,用户可以使用Matlab的ImageProcessing Toolbox中的相关函数,对图像进行退化处理和模型建立,并通过最小二乘法求解配准参数。
图像处理matlab及图像融合图像镶嵌图像拼接
图像处理matlab及图像融合图像镶嵌图像拼接在实际的对图像处理过程中,由于我们读出的图像是unit8型,⽽在MATLAB的矩阵运算中要求所有的运算变量为double型(双精度型)。
因此读出的图像数据不能直接进⾏相加求平均,因此必须使⽤⼀个函数将图像数据转换成双精度型数据。
MATLAB中提供了这样的函数:im2double函数,其语法格式为:I2 = im2double(I1)其中I1是输⼊的图像数据,它可能是unit8或unit16型数据,通过函数的变化输出I2为⼀个double型数据,这样两图像数据就可以⽅便的进⾏相加等代数运算.要把double的图像(范围是0到1)再次转化为256灰度值的,可以这样Igrey= uint8(I2*255)图像类型转换函数:dither() 通过颜⾊抖动,把真彩图像转换成索引图像或灰度图象转换成⼆值图像gray2ind() 将灰度图像(或⼆值图像)转换成索引图像grayslice() 通过设定的阈值将灰度图象转换成索引图像im2bw() 通过设定亮度阈值将灰度、真彩、索引图象转换成⼆值图像ind2gray() 将索引图象转换成灰度图象ind2rgb() 将索引图象转换成真彩⾊图像mat2gray() 将⼀个数据矩阵转换成⼀幅灰度图象rgb2gray() 将真彩转换成灰度图象rgb2ind() 将真彩转换成索引图象图像类型与类型间的转换1。
索引图像:包括⼀个数据矩阵X和⼀个⾊图阵MAP。
矩阵元素值指向MAP中的特定颜⾊向量。
2。
灰度图像:数据矩阵I,I中的数据代表了颜⾊灰度值。
矩阵中的元素可以是double类型、8位或16位⽆符号的整数类型。
3。
RGB图像:即真彩图像。
矩阵中每个元素为⼀个数组,数组的元素定义了像素的红、绿、蓝颜⾊值。
RGB数组可以是double类型、8位或16位⽆符号的整数类型。
4。
⼆值图像:⼀个数据阵列,每个象素只能取0或1。
矩阵的基本运算⾏列式求值:det(A)矩阵加减:+、-矩阵相乘:*矩阵左除:A/B %相当于inv(A)*B矩阵右除:A\B %相当于A*inv(B)矩阵的幂:^矩阵转置:'矩阵求共轭(实部相同,虚部相反):conj(X)矩阵求逆:inv(X)级数的求和与收敛symsum(fun,var,a,b):其中fun是通项表达式,var为求和变量,a为求和起点,b为求和终点例如:I为1/[n*(2n+1)]从1到正⽆穷的和,求Isyms n;f1=1/(n*(2*n+1));I=symsum(f1,n,1,inf)计算结果为:I =2-2*log(2)空间曲⾯mesh()函数语法:mesh(Z):mesh(X,Y,Z,C):其中C是⽤来定义相应点颜⾊等属性的数组例:求x^2+y^2=z的空间曲⾯x=-4:4;y=x;[X,Y]=meshgrid(x,y);%⽣成x,y坐标Z=X.^2+Y.^2;mesh(X,Y,Z)曲⾯图[x,y]=meshgrid(xa,ya) 当xa,ya分别为m维和n维⾏向量,得到x和y均为n⾏m列矩阵。
基于ICP 算法的多视点云配准方法
基于ICP 算法的多视点云配准方法作者:邹敏来源:《科技创新与生产力》 2017年第2期邹敏(安徽理工大学测绘学院,安徽淮南 232001)摘要:多视点云配准是三维激光扫描数据处理过程中一项非常重要的任务,经典ICP算法是多视点云配准算法中一项重要方法。
重点阐述了ICP算法的原理、解算步骤与推导过程,针对经典ICP算法不适用于大旋转角度的缺陷,进行了有效改进,在进行ICP算法解算前先进行一次粗配准,并对通过三维激光扫描采集的实测点云数据进行验证,实验表明该改进算法正确有效,适用于任意旋转角度的多视点云配准。
关键词:多视点云配准;ICP算法;三维激光扫描;点云数据采集中图分类号:P207 文献标志码:A DOI:10.3969/j.issn.1674-9146.2017.02.074三维激光扫描技术由于其测速快、精度高、效率高等优点,被称为是继全球定位系统(Global Positioning System,GPS)技术以来又一次重大技术革命[1]。
三维激光扫描点云数据处理大致可分为预处理、多视点云配准、三维模型建立以及贴图渲染等步骤,其中多视点云配准是三维激光扫描技术中的一项核心任务,其配准的精度将直接影响三维模型建立的精度。
由Besl和Mckay[2]在1992年提出的迭代最近点(Iterative Closest Point,ICP)算法是多视点云数据配准中最为经典的方法之一,该方法的基本思想是通过查找最邻近点,拉近与最邻近点之间距离,并不断迭代,设置合理的阈值,直到相应点对之间的距离之和最小或小于阈值为止。
由于ICP算法具有较高的精确度,很快就成为了多视点云配准中的主流算法[3-4]。
随着ICP算法的广泛应用,研究者们对该算法做了许多详细的研究,分析出该算法存在不适用于大旋转角度的缺陷。
因此笔者详细介绍了ICP算法的基本原理,并针对这一缺陷,进行了有效改进:在利用ICP算法进行点云数据的精细配准前,先对点集进行了粗配准,保证了ICP算法下的小旋转角度,从而保证了该算法的正确性。
Matlab的图像匹配和图像配准技术
Matlab的图像匹配和图像配准技术Matlab是一种广泛应用于科学计算和工程领域的软件平台,其中图像处理是它的一个重要应用领域之一。
在图像处理中,图像匹配和图像配准是两个核心概念和技术。
本文将介绍Matlab中的图像匹配和图像配准技术,探讨其原理、方法和应用。
一、图像匹配图像匹配是指在两个或多个图像中寻找相对应的特征点或区域,以实现图像间的关联和对比。
图像匹配通常用于图像检索、目标跟踪和图像融合等应用。
Matlab提供了多种图像匹配算法和函数,下面将介绍其中两个常用的方法。
1. 特征点匹配特征点匹配是一种常见的图像匹配方法,它通过提取图像中的关键特征点,并根据这些特征点的描述子进行匹配。
Matlab中的SIFT(尺度不变特征变换)和SURF(加速稳健特征)算法是两个常用的特征点匹配算法。
这些算法能够在图像中提取出具有鲁棒性和不变性的特征点,并通过匹配它们来实现图像的对比和关联。
2. 模板匹配模板匹配是另一种常见的图像匹配方法,它通过在图像中搜索与给定模板相似的区域来实现匹配。
在Matlab中,模板匹配通常使用归一化互相关(NCC)或归一化平方差(NSSD)等方法。
这些方法可以计算模板与图像中相似区域的相似度,并找到最佳匹配位置。
二、图像配准图像配准是指将多幅图像在几何和灰度上进行变换和校正,使它们在某种准则下达到最佳对齐的过程。
图像配准常用于医学影像分析、遥感图像处理和计算机视觉等领域。
Matlab提供了多种图像配准方法和函数,下面将介绍其中两个常用的方法。
1. 点对点配准点对点配准是一种常见的图像配准方法,它通过选择一些对应的特征点或控制点,根据它们之间的几何关系进行图像变换和平移。
Matlab中的imregister函数可以实现点对点配准,通过计算图像间的变换矩阵来对图像进行配准。
2. 图像相似度配准图像相似度配准是另一种常见的图像配准方法,它通过最小化图像间的相似度度量来实现配准。
Matlab中的imregcorr函数可以计算图像间的相关系数,通过最大化相关系数来优化配准结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
function [TR, TT] =icp(model,data,max_iter,min_iter,fitting,thres,init_flag,tes_flag,refpn t)% ICP Iterative Closest Point Algorithm. Takes use of% Delaunay tesselation of points in model.%% Ordinary usage:%% [R, T] = icp(model,data)%% ICP fit points in data to the points in model.% Fit with respect to minimize the sum of square% errors with the closest model points and data points.%% INPUT:%% model - matrix with model points, [Pm_1 Pm_2 ... Pm_nmod]% data - matrix with data points, [Pd_1 Pd_2 ... Pd_ndat]%% OUTPUT:%% R - rotation matrix and% T - translation vector accordingly so%% newdata = R*data + T .%% newdata are transformed data points to fit model%%% Special usage:%% icp(model) or icp(model,tes_flag)%% ICP creates a Delaunay tessellation of points in% model and save it as global variable Tes. ICP also% saves two global variables ir and jc for tes_flag=1 (default) or% Tesind and Tesver for tes_flag=2, which% makes it easy to find in the tesselation. To use the global variables % in icp, put tes_flag to 0.%%% Other usage:%% [R, T] = icp(model,data,max_iter,min_iter,...% fitting,thres,init_flag,tes_flag)%% INPUT:%% max_iter - maximum number of iterations. Default=104%% min_iter - minimum number of iterations. Default=4%% fitting - =2 Fit with respect to minimize the sum of square errors. (default)% alt. =[2,w], where w is a weight vector corresponding to data.% w is a vector of same length as data.% Fit with respect to minimize the weighted sum of square errors.% =3 Fit with respect to minimize the sum to the amount 0.95 % of the closest square errors.% alt. =[3,lambda], 0.0<lambda<=1.0, (lambda=0.95 default) % In each iteration only the amount lambda of the closest% points will affect the translation and rotation.% If 1<lambda<=size(data,2), lambda integer, only the number lambda% of the closest points will affect the translation and% rotation in each iteration.%% thres - error differens threshold for stop iterations. Default 1e-5%% init_flag - =0 no initial starting transformation% =1 transform data so the mean value of% data is equal to mean value of model.% No rotation. (init_flag=1 default)%% tes_flag - =0 No new tesselation has to be done. There% alredy exists one for the current model points.% =1 A new tesselation of the model points will% be done. (default)% =2 A new tesselation of the model points will% be done. Another search strategy than tes_flag=1% =3 The closest point will be find by testing% all combinations. No Delaunay tesselation will be done. %% refpnt - (optional) (An empty vector is default.) refpnt is a point corresponding to the% set of model points wich correspondig data point has to be find.% How the points are weighted depends on the output from the % function weightfcn found in the end of this m-file. The input in weightfcn is the% distance between the closest model point and refpnt.%% To clear old global tesselation variables run: "clear global Tes ir jc" (tes_flag=1)% or run: "clear global Tes Tesind Tesver" (tes_flag=2) in Command Window. %% m-file can be downloaded for free at%/matlabcentral/fileexchange/loadFile.do?objectId=12627&objectType=FILE%% icp version 1.4%% written by Per Bergström 2007-03-07if nargin<1error('To few input arguments!');elseif or(nargin==1,nargin==2)bol=1;refpnt=[];if nargin==2if isempty(data)tes_flag=1;elseif isscalar(data)tes_flag=data;if not(tes_flag==1 | tes_flag==2)tes_flag=1;endelsebol=0;endelsetes_flag=1;endif bolglobal MODELif isempty(model)error('Model can not be an empty matrix.');endif (size(model,2)<size(model,1))MODEL=model';TR=eye(size(model,2));TT=zeros(size(model,2),1);elseMODEL=model;TR=eye(size(model,1));TT=zeros(size(model,1),1);endif (size(MODEL,2)==size(MODEL,1))error('This icp method demands the number of MODEL points to be greater then the dimension.');endicp_struct(tes_flag);returnendendglobal MODEL DATA TR TTif isempty(model)error('Model can not be an empty matrix.');endif (size(model,2)<size(model,1))MODEL=model';elseMODEL=model;endif (size(data,2)<size(data,1))data=data';DATA=data;elseDATA=data;endif size(DATA,1)~=size(MODEL,1)error('Different dimensions of DATA and MODEL!');endif nargin<9refpnt=[];if nargin<8tes_flag=1;if nargin<7init_flag=1;if nargin<6thres=1e-5; % threshold to icp iterations if nargin<5fitting=2; % fitting methodif nargin<4min_iter=4; % min number of icp iterationsif nargin<3max_iter=104; % max number of icp iterationsendendendendendendelseif nargin>9warning('Too many input arguments!');endif isempty(tes_flag)tes_flag=1;elseif not(tes_flag==0 | tes_flag==1 | tes_flag==2 | tes_flag==3)init_flag=1;warning('init_flag has been changed to 1');endif and((size(MODEL,2)==size(MODEL,1)),tes_flag~=0)error('This icp method demands the number of model points to be greater then the dimension.');endif isempty(min_iter)min_iter=4;endif isempty(max_iter)max_iter=100+min_iter;endif max_iter<min_iter;max_iter=min_iter;warning('max_iter<min_iter , max_iter has been changed to be equal min_iter');endif min_iter<0;min_iter=0;warning('min_iter<0 , min_iter has been changed to be equal 0');endif isempty(thres)thres=1e-5;elseif thres<0thres=abs(thres);warning('thres negative , thres have been changed to -thres');endif isempty(fitting)fitting=2;elseif fitting(1)==2[fi1,fi2]=size(fitting);lef=max([fi1,fi2]);if lef>1if fi1<fi2fitting=fitting';endif lef<(size(data,2)+1)warning('Illegeal size of fitting! Unweighted minimization will be used.');fitting=2;elseif min(fitting(2:(size(data,2)+1)))<0warning('Illegeal value of the weights! Unweighted minimization will be used.');fitting=2;elseif max(fitting(2:(size(data,2)+1)))==0warning('Illegeal values of the weights! Unweighted minimization will be used.');fitting=2;elsesu=sum(fitting(2:(size(data,2)+1)));fitting(2:(size(data,2)+1))=fitting(2:(size(data,2)+1))/su;thres=thres/su;endendelseif fitting(1)==3if length(fitting)<2fitting=[fitting,round(0.95*size(data,2))];elseif fitting(2)>1if fitting(2)>floor(fitting(2))fitting(2)=floor(fitting(2));warning(['lambda has been changed to',num2str(fitting(2)),'!']);endif fitting(2)>size(data,2)fitting(2)=size(data,2);warning(['lambda has been changed to',num2str(fitting(2)),'!']);endelseif fitting(2)>0if fitting(2)<=0.5warning('lambda small. Troubles might occur!');endfitting(2)=round(fitting(2)*size(data,2));elseif fitting(2)<=0fitting(2)=round(0.95*size(data,2));warning(['lambda has been changed to ',num2str(fitting(2)),'!']);endelsefitting=2;warning('fitting has been changed to 2');endif isempty(init_flag)init_flag=1;elseif not(init_flag==0 | init_flag==1)init_flag=1;warning('init_flag has been changed to 1');endif (size(refpnt,2)>size(refpnt,1))refpnt=refpnt';endif (size(refpnt,1)~=size(DATA,1))if not(isempty(refpnt))refpnt=[];warning('Dimension of refpnt dismatch. refpnt is put to [] (empty matrix).');endendif (size(refpnt,2)>1)refpnt=refpnt(:,1);warning('Only the first point in refpnt is used.');end% Start the ICP algorithmN = size(DATA,2);icp_init(init_flag,fitting); % initiate a starting rotation matrix and starting translation vectortes_flag=icp_struct(tes_flag); % construct a Delaunay tesselation and two vectors make it easy to find in TesERROR=icp_closest_start(tes_flag,fitting); % initiate a vector with indices of closest MODEL pointsicp_transformation(fitting,[]); % find transformationDATA = TR*data; % apply transformationDATA=DATA+repmat(TT,1,N); %for iter=1:max_iterolderror = ERROR;ERROR=icp_closest(tes_flag,fitting); % find indices of closest MODEL points and total errorif iter<min_itericp_transformation(fitting,[]); % find transformation elseicp_transformation(fitting,refpnt); % find transformation endDATA = TR*data; % apply transformationDATA=DATA+repmat(TT,1,N); %if iter>=min_iterif abs(olderror-ERROR) < thresbreakendendend %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function icp_init(init_flag,fitting)%function icp_init(init_flag)%ICP_INIT Initial alignment for ICP.global MODEL DATA TR TTif init_flag==0TR=eye(size(MODEL,1));TT=zeros(size(MODEL,1),1);elseif init_flag==1N = size(DATA,2);if fitting(1)==2if length(fitting)==1mem=mean(MODEL,2); med=mean(DATA,2);elsemem=MODEL*fitting(2:(N+1)); med=DATA*fitting(2:(N+1));endelsemem=mean(MODEL,2); med=mean(DATA,2);endTR=eye(size(MODEL,1));TT=mem-med;DATA=DATA+repmat(TT,1,N); % apply transformationelseerror('Wrong init_flag');end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%function tes_flag=icp_struct(tes_flag)if tes_flag==0global irif isempty(ir)global Tesindif isempty(Tesind)error('No tesselation system exists');elsetes_flag=2;endelsetes_flag=1;endelseif tes_flag==3returnelseglobal MODEL Tes[m,n]=size(MODEL);if m==1[so1,ind1]=sort(MODEL);Tes=zeros(n,2);Tes(1:(n-1),1)=ind1(2:n)';Tes(2:n,2)=ind1(1:(n-1))';Tes(1,2)=Tes(1,1);Tes(n,1)=Tes(n,2);elseTes=delaunayn(MODEL');if isempty(Tes)mem=mean(MODEL,2);MODELm=MODEL-repmat(mem,1,n);[U,S,V]=svd(MODELm*MODELm');onbasT=U(:,diag(S)>1e-8)'MODELred=onbasT*MODEL;if size(MODELred,1)==1[so1,ind1]=sort(MODELred);Tes=zeros(n,2);Tes(1:(n-1),1)=ind1(2:n)';Tes(2:n,2)=ind1(1:(n-1))';Tes(1,2)=Tes(1,1);Tes(n,1)=Tes(n,2);Tes(ind1,:)=Tes(:,:);elseTes=delaunayn(MODELred');endendendTes=sortrows(sort(Tes,2));[mT,nT]=size(Tes);if tes_flag==1global ir jcnum=zeros(1,n);for i=1:mTfor j=1:nTnum(Tes(i,j))=num(Tes(i,j))+1;endendnum=cumsum(num);jc=ones(1,n+1);jc(2:end)=num+jc(2:end);ir=zeros(1,num(end));ind=jc(1:(end-1));%% calculate ir;for i=1:mTfor j=1:nTir(ind(Tes(i,j)))=i;ind(Tes(i,j))=ind(Tes(i,j))+1;endendelse% tes_flag==2Tesind=zeros(mT,nT);Tesver=zeros(mT,nT);couvec=zeros(mT,1);for i=1:(mT-1)for j=(i+1):mTif couvec(i)==nTbreak;elseif Tes(i,1)==Tes(j,1)if nT==2Tesind(i,2)=j;Tesind(j,2)=i;Tesver(i,2)=2;Tesver(j,2)=2;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;elsefor k=2:nTfor kk=k:nTifall(Tes(i,[2:(k-1),(k+1):nT])==Tes(j,[2:(kk-1),(kk+1):nT])) Tesind(i,k)=j;Tesind(j,kk)=i;Tesver(i,k)=kk;Tesver(j,kk)=k;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;endendif or(couvec(i)==nT,couvec(j)==nT)breakendendendelseif Tes(i,1)==Tes(j,2)if nT==2Tesind(i,2)=j;Tesind(j,1)=i;Tesver(i,2)=1;Tesver(j,1)=2;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;elsefor k=2:nTif all(Tes(i,[2:(k-1),(k+1):nT])==Tes(j,3:nT)) Tesind(i,k)=j;Tesind(j,1)=i;Tesver(i,k)=1;Tesver(j,1)=k;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;endif or(couvec(i)==nT,couvec(j)==nT)breakendendendelseif Tes(i,2)==Tes(j,1)if nT==2Tesind(i,1)=j;Tesind(j,2)=i;Tesver(i,1)=2;Tesver(j,2)=1;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;elsefor k=2:nTif all(Tes(i,3:nT)==Tes(j,[2:(k-1),(k+1):nT])) Tesind(i,1)=j;Tesind(j,k)=i;Tesver(i,1)=k;Tesver(j,k)=1;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;endif or(couvec(i)==nT,couvec(j)==nT)breakendendendelseif Tes(i,2)==Tes(j,2)if nT==2Tesind(i,1)=j;Tesind(j,1)=i;Tesver(i,1)=1;Tesver(j,1)=1;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;if Tes(j,1)>Tes(i,2)break;endelseif all(Tes(i,3:end)==Tes(j,3:end))Tesind(i,1)=j;Tesind(j,1)=i;Tesver(i,1)=1;Tesver(j,1)=1;couvec(i)=couvec(i)+1;couvec(j)=couvec(j)+1;endelseif Tes(j,1)>Tes(i,2)break;endendendendend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%function ERROR=icp_closest_start(tes_flag,fitting)% Usage:% ERROR = icp_closest_start(tes_flag)%% ERROR=sum of all errors between points in MODEL and points in DATA.%% ICP_CLOSEST_START finds indexes of closest MODEL points for each point in DATA.% The _start version allocates memory for iclosest and finds the closest MODEL points% to the DATA pointsif tes_flag==3global MODEL DATA iclosestmd=size(DATA,2);mm=size(MODEL,2);iclosest=zeros(1,md);ERROR=0;for id=1:mddist=Inf;for im=1:mmdista=norm(MODEL(:,im)-DATA(:,id));if dista<disticlosest(id)=im;dist=dista;endendERROR=ERROR+err(dist,fitting,id);endelseif tes_flag==1global MODEL DATA Tes ir jc iclosestmd=size(DATA,2);iclosest=zeros(1,md);mid=round(md/2);iclosest(mid)=round(size(MODEL,2)/2);bol=logical(1);while bolbol=not(bol);distc=norm(DATA(:,mid)-MODEL(:,iclosest(mid)));distcc=2*distc;for in=ir(jc(iclosest(mid)):(jc(iclosest(mid)+1)-1))for ind=Tes(in,:)distcc=norm(DATA(:,mid)-MODEL(:,ind));if distcc<distcdistc=distcc;bol=not(bol);iclosest(mid)=ind;break;endendif bolbreak;endendendERROR=err(distc,fitting,mid);for id = (mid+1):mdiclosest(id)=iclosest(id-1);bol=not(bol);while bolbol=not(bol);distc=norm(DATA(:,id)-MODEL(:,iclosest(id)));distcc=2*distc;for in=ir(jc(iclosest(id)):(jc(iclosest(id)+1)-1)) for ind=Tes(in,:)distcc=norm(DATA(:,id)-MODEL(:,ind));if distcc<distcdistc=distcc;bol=not(bol);iclosest(id)=ind;break;endendif bolbreak;endendendERROR=ERROR+err(distc,fitting,id);endfor id=(mid-1):-1:1iclosest(id)=iclosest(id+1);bol=not(bol);while bolbol=not(bol);distc=norm(DATA(:,id)-MODEL(:,iclosest(id)));distcc=2*distc;for in=ir(jc(iclosest(id)):(jc(iclosest(id)+1)-1)) for ind=Tes(in,:)distcc=norm(DATA(:,id)-MODEL(:,ind));if distcc<distcdistc=distcc;bol=not(bol);iclosest(id)=ind;break;endendif bolbreak;endendendERROR=ERROR+err(distc,fitting,id);endelse% tes_flag==2global MODEL DATA Tes Tesind Tesver icTesind iclosestmd=size(DATA,2);iclosest=zeros(1,md);icTesind=zeros(1,md);[mTes,nTes]=size(Tes);mid=round(md*0.5);icTesind(mid)=round(mTes*0.5);iclosest(mid)=max(Tesind(icTesind(mid),:));visited=logical(zeros(1,mTes));visited(icTesind(mid))=1;di2vec=sqrt(sum((repmat(DATA(:,mid),1,nTes)-MODEL(:,Tes(icTesind(mid),: ))).^2,1));bol=logical(1);while bol[so,in]=sort(di2vec);for ii=nTes:-1:2Ti=Tesind(icTesind(mid),in(ii));if Ti>0if not(visited(Ti))break;endendendif Ti==0bol=not(bol);elseif visited(Ti)bol=not(bol);elseTv=Tesver(icTesind(mid),in(ii));visited(Ti)=1;icTesind(mid)=Ti;di2vec([1:(Tv-1),(Tv+1):nTes])=di2vec([1:(in(ii)-1),(in(ii)+1):nTes]); di2vec(Tv)=norm(DATA(:,mid)-MODEL(:,Tes(Ti,Tv)));endendiclosest(mid)=Tes(icTesind(mid),in(1));ERROR=err(so(1),fitting,mid);for id = (mid+1):mdiclosest(id)=iclosest(id-1);icTesind(id)=icTesind(id-1);visited(:)=0;visited(icTesind(id))=1;di2vec=sqrt(sum((repmat(DATA(:,id),1,nTes)-MODEL(:,Tes(icTesind(id),:)) ).^2,1));bol=not(bol);while bol[so,in]=sort(di2vec);for ii=nTes:-1:2Ti=Tesind(icTesind(id),in(ii));if Ti>0if not(visited(Ti))break;endendendif Ti==0bol=not(bol);elseif visited(Ti)bol=not(bol);elseTv=Tesver(icTesind(id),in(ii));visited(Ti)=1;icTesind(id)=Ti;di2vec([1:(Tv-1),(Tv+1):nTes])=di2vec([1:(in(ii)-1),(in(ii)+1):nTes]); di2vec(Tv)=norm(DATA(:,id)-MODEL(:,Tes(Ti,Tv)));endendiclosest(id)=Tes(icTesind(id),in(1));ERROR=ERROR+err(so(1),fitting,id);endfor id=(mid-1):-1:1iclosest(id)=iclosest(id+1);icTesind(id)=icTesind(id+1);visited(:)=0;visited(icTesind(id))=1;di2vec=sqrt(sum((repmat(DATA(:,id),1,nTes)-MODEL(:,Tes(icTesind(id),:)) ).^2,1));bol=not(bol);while bol[so,in]=sort(di2vec);for ii=nTes:-1:2Ti=Tesind(icTesind(id),in(ii));if Ti>0if not(visited(Ti))break;endendendif Ti==0bol=not(bol);elseif visited(Ti)bol=not(bol);elseTv=Tesver(icTesind(id),in(ii));visited(Ti)=1;icTesind(id)=Ti;di2vec([1:(Tv-1),(Tv+1):nTes])=di2vec([1:(in(ii)-1),(in(ii)+1):nTes]);di2vec(Tv)=norm(DATA(:,id)-MODEL(:,Tes(Ti,Tv)));endendiclosest(id)=Tes(icTesind(id),in(1));ERROR=ERROR+err(so(1),fitting,id);endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%function ERROR=icp_closest(tes_flag,fitting)% Usage:% ERROR = icp_closest(tes_flag,fitting)%% ERROR=sum of all errors between points in model and points in data.%% ICP_CLOSEST finds indexes of closest model points for each point in data.if tes_flag==3global MODEL DATA iclosestmd=size(DATA,2);mm=size(MODEL,2);ERROR=0;for id=1:mddist=Inf;for im=1:mmdista=norm(MODEL(:,im)-DATA(:,id));if dista<disticlosest(id)=im;dist=dista;endendERROR=ERROR+err(dist,fitting,id);endelseif tes_flag==1global MODEL DATA Tes ir jc iclosest[mTes,nTes]=size(Tes);ERROR=0;bol=logical(0);for id=1:size(DATA,2)bol=not(bol);while bolbol=not(bol);distc=norm(DATA(:,id)-MODEL(:,iclosest(id)));distcc=2*distc;for in=ir(jc(iclosest(id)):(jc(iclosest(id)+1)-1)) for ind=Tes(in,:)distcc=norm(DATA(:,id)-MODEL(:,ind));if distcc<distcdistc=distcc;bol=not(bol);iclosest(id)=ind;break;endendif bolbreak;endendendERROR=ERROR+err(distc,fitting,id);endelse% tes_flag==2global MODEL DATA Tes Tesind Tesver iclosest icTesind[mTes,nTes]=size(Tes);ERROR=0;bol=logical(0);visited=logical(zeros(1,mTes));for id=1:size(DATA,2)visited(:)=0;visited(icTesind(id))=1;di2vec=sqrt(sum((repmat(DATA(:,id),1,nTes)-MODEL(:,Tes(icTesind(id),:)) ).^2,1));bol=not(bol);while bol[so,in]=sort(di2vec);for ii=nTes:-1:2Ti=Tesind(icTesind(id),in(ii));if Ti>0if not(visited(Ti))break;endendendif Ti==0bol=not(bol);elseif visited(Ti)bol=not(bol);elseTv=Tesver(icTesind(id),in(ii));visited(Ti)=1;icTesind(id)=Ti;di2vec([1:(Tv-1),(Tv+1):nTes])=di2vec([1:(in(ii)-1),(in(ii)+1):nTes]); di2vec(Tv)=norm(DATA(:,id)-MODEL(:,Tes(Ti,Tv)));endendiclosest(id)=Tes(icTesind(id),in(1));ERROR=ERROR+err(so(1),fitting,id);endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function icp_transformation(fitting,refpnt)% Finds the rotation and translation of the DATA pointsglobal MODEL DATA iclosest TR TTM=size(DATA,1);N=size(DATA,2);bol=0;if not(isempty(refpnt))bol=1;dis=sqrt(sum((MODEL(:,iclosest)-repmat(refpnt,1,N)).^2,1)); weights=weightfcn(dis');endif bolif fitting(1)==2if length(fitting)>1weights=fitting(2:(N+1)).*weights;weights=weights/sum(weights);endmed=DATA*weights; mem=MODEL(:,iclosest)*weights;A=DATA-repmat(med,1,N);B=MODEL(:,iclosest)-repmat(mem,1,N);for i=1:NA(:,i)=weights(i)*A(:,i);endelseif fitting(1)==3V=sum((DATA-MODEL(:,iclosest)).^2,1);[soV,in]=sort(V);ind=in(1:fitting(2));weights(ind)=weights(ind)/sum(weights(ind));med=DATA(:,ind)*weights(ind);mem=MODEL(:,iclosest(ind))*weights(ind);A=DATA(:,ind)-repmat(med,1,fitting(2));B=MODEL(:,iclosest(ind))-repmat(mem,1,fitting(2));for i=1:fitting(2)A(:,i)=weights(ind(i))*A(:,ind(i));endendelseif fitting(1)==2if length(fitting)==1med=mean(DATA,2); mem=mean(MODEL(:,iclosest),2);A=DATA-repmat(med,1,N);B=MODEL(:,iclosest)-repmat(mem,1,N);elsemed=DATA*fitting(2:(N+1));mem=MODEL(:,iclosest)*fitting(2:(N+1));A=DATA-repmat(med,1,N);B=MODEL(:,iclosest)-repmat(mem,1,N);for i=1:NA(:,i)=fitting(i+1)*A(:,i);endendelseif fitting(1)==3V=sum((DATA-MODEL(:,iclosest)).^2,1);[soV,in]=sort(V);ind=in(1:fitting(2));med=mean(DATA(:,ind),2); mem=mean(MODEL(:,iclosest(ind)),2); A=DATA(:,ind)-repmat(med,1,fitting(2));B=MODEL(:,iclosest(ind))-repmat(mem,1,fitting(2));endend[U,S,V] = svd(B*A');U(:,end)=U(:,end)*det(U*V');R=U*V';% Compute the translationT=(mem-R*med);TR=R*TR; TT=R*TT+T;function ERR=err(dist,fitting,ind)if fitting(1)==2if (ind+1)>length(fitting)ERR=dist^2;elseERR=fitting(ind+1)*dist^2;endelseif fitting(1)==3ERR=dist^2;elseERR=0;warning('Unknown value of fitting!');endfunction weights=weightfcn(distances)maxdistances=max(distances);mindistances=min(distances);if maxdistances>1.1*mindistancesweights=1+mindistances/(maxdistances-mindistances)-distances/(maxdistan ces-mindistances);elseweights=maxdistances+mindistances-distances;endweights=weights/sum(weights);。