VTK——使用ICP算法进行模型配准

ICP算法

迭代最近点(Iterative Closest Point,ICP)算法是一种用于两个三维形状之间几何对齐(也叫做配准)的计算方法。通常,这两个形状至少有一个是点云数据。ICP算法用于最小化源点云与目标点云之间点到点的距离,从而寻找两者之间的最佳匹配变换(通常是刚体变换,但也可能是仿射或其他形式的变换)。

算法流程

初始化:设定初始猜测的变换参数(通常为单位矩阵)。
关联点:对于源点云中的每一个点,找到目标点云中的最近点。
最小化误差:找到一个变换,该变换能最小化源点到对应目标点之间的距离。
更新变换:将找到的变换应用于源点云。
收敛检查:检查误差或变换是否在一定阈值内收敛。如果是,则算法停止。否则,返回步骤2。

数学公式

设源点云 P 和目标点云Q 由 n 个点组成,其中pi​∈P 和 qi​∈Q。我们想要找到一个变换 T,使得总体误差 E 最小。
在这里插入图片描述
对于刚体变换,T 可以由旋转矩阵 R 和平移矢量 t 组成:
在这里插入图片描述
这个算法的优点是简单、直观、实现相对容易,缺点是容易收敛到局部最优解和计算复杂性较高。经常应用到机器人导航、对象识别、三维建模等场景。

代码流程

  1. 计算模型的质心:使用 VTK 的 vtkCenterOfMass 类计算 STL 模型的质心。这个质心用于后续找出模型中距质心最远的几个点。

  2. 找出四个距离质心最远的点:迭代遍历模型所有的点,并使用 VTK 的 vtkMath::Distance2BetweenPoints 方法计算每个点与质心的距离。找出四个距离质心最远的点,并保存它们的索引。

  3. 创建一个新的 vtkPolyData 对象,包含这四个点:使用 vtkPoints 和 vtkCellArray 创建一个新的 vtkPolyData 对象,这个对象只包括距离质心最远的四个点。

  4. 创建另一个 vtkPolyData 对象,包含在 3D 模型中选定的点:这个对象是算法的目标点集,也是使用 vtkPoints 和 vtkCellArray 创建的。

  5. 应用 ICP 算法:使用 VTK 的 vtkIterativeClosestPointTransform 类进行 ICP 对齐。设置源点(STL模型中的四个点)和目标点(3D模型中选定的点),并启动算法。

  6. 应用变换到 STL 模型:通过 vtkTransformPolyDataFilter 将 ICP 算法得出的变换应用到原始的 STL 模型上。

  7. 更新渲染:最后,更新模型的渲染,以反映应用了 ICP 变换后的新状态。

代码的核心是使用 ICP 算法进行两组点之间的最优对齐。它首先选取 STL 模型中四个特定的点(距离质心最远的点),然后用这些点与 3D 模型中预先选定的点进行对齐。通过这种方式,算法能够找到一个最佳的刚体变换,将 STL 模型与 3D 模型对齐。在这里面,所做的只是一个简单的配准示例。因为两个模型特征点的选取和ICP算法的应用都是比较复杂的,需要不断的尝试和优化,才能得到一个比较好的效果。


   void performModelAlignment() {

    
    // Calculate Model Center
    double modelCenter[3];
    auto centerCalculator = vtkSmartPointer<vtkCenterOfMass>::New();
    centerCalculator->SetInputData(reader->GetOutput());
    centerCalculator->SetUseScalarsAsWeights(false);
    centerCalculator->Update();
    centerCalculator->GetCenter(modelCenter);

    // Find Distant Points from Center
    auto modelPoints = reader->GetOutput()->GetPoints();
    std::vector<vtkIdType> distantPoints = findDistantPoints(modelPoints, modelCenter, 4);

    // Construct PolyData for Distant Points in STL
    auto stlSelectedPointsData = createPolyDataFromPoints(modelPoints, distantPoints);

    // Construct PolyData for Selected Points in 3D Model
    auto modelSelectedPointsData = createPolyDataFromPoints(featurePoints);

    // Perform ICP
    auto icpTransform = vtkSmartPointer<vtkIterativeClosestPointTransform>::New();
    icpTransform->SetSource(stlSelectedPointsData);
    icpTransform->SetTarget(modelSelectedPointsData);
    icpTransform->GetLandmarkTransform()->SetModeToRigidBody();
    icpTransform->Modified();
    icpTransform->Update();

    // Apply Transformation
    applyTransformationToModel(icpTransform, reader->GetOutput());

}

std::vector<vtkIdType> findDistantPoints(vtkSmartPointer<vtkPoints> points, double center[3], int numPoints) {
    std::vector<vtkIdType> distantPoints;
    // ... (Same logic to find distant points)
    return distantPoints;
}

vtkSmartPointer<vtkPolyData> createPolyDataFromPoints(vtkSmartPointer<vtkPoints> points, std::vector<vtkIdType> &selectedIds) {
    auto polyData = vtkSmartPointer<vtkPolyData>::New();
    auto selectedPoints = vtkSmartPointer<vtkPoints>::New();
    auto vertices = vtkSmartPointer<vtkCellArray>::New();
    // ... (Same logic to create PolyData)
    return polyData;
}

void applyTransformationToModel(vtkSmartPointer<vtkIterativeClosestPointTransform> icpTransform, vtkSmartPointer<vtkPolyData> originalData) {
    auto transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
    transformFilter->SetInputData(originalData);
    transformFilter->SetTransform(icpTransform);
    transformFilter->Update();
    vtkPolyDataMapper::SafeDownCast(m_modelActor->GetMapper())->SetInputData(transformFilter->GetOutput());
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: vtk是一种图形库,用于可视化数据。在vtk中,“点”、“线”和“面”是常见的几何元素。下面是关于这些元素的一些示例: 1. 点(Point):点是空间中具有坐标位置的最基本的几何元素。在vtk中,我们可以创建一个或多个点,并指定它们的坐标。例如,我们可以创建一个点的集合,表示星空中的一些恒星的位置。每个点都有自己的坐标,可以在三维空间中进行可视化。 2. 线(Line):线是由两个或更多个连接起来的点组成的几何形状。在vtk中,我们可以使用点的坐标来创建一条直线。例如,我们可以创建一个由两个点组成的线,表示一条直线段的路径。这条直线可以用来表示一条河流的流程,或者是一辆车在道路上行驶的路径。 3. 面(Surface):面是由三个或更多个连接起来的点和线组成的几何形状。在vtk中,我们可以使用点的坐标和线的连接关系来创建一个面。例如,我们可以创建一个三角形的面,通过指定三个点的坐标来定义。这个三角形可以用来表示一个地面的形状,或者是一个房屋的屋顶的形状。 总之,vtk提供了一种便捷的方式来创建和可视化各种几何元素,包括点、线和面。通过使用vtk,我们可以将这些几何元素在三维空间中进行可视化,并用于表示和展示各种数据的形状和结构。 ### 回答2: VTK(Visualization Toolkit)是一个强大的图形可视化库,它提供了丰富的功能和工具,可以用于创建各种类型的图形对象和可视化效果。在VTK中,可以使用点、线和面作为基本的图形元素。 在VTK中,点是最简单的图形元素之一。它可以用于表示空间中的一个坐标点,具有位置属性。例如,我们可以使用VTK创建一个点的可视化效果,通过设置其位置和颜色来定义点的属性,从而实现对点的可视化表达。 线是由多个点连接而成的线段。在VTK中,可以使用一系列的点来创建一条线,并通过设置线的属性,如线宽、颜色、透明度等来实现线的可视化效果。例如,我们可以通过VTK创建一个由多个点组成的路径,用来表示动态的物体运动轨迹。 面是由多条连续的线组成的封闭区域。在VTK中,可以使用一系列的坐标点来定义一个封闭的多边形,并通过设置面的属性,如颜色、透明度、纹理等来实现面的可视化效果。例如,我们可以使用VTK创建一个立方体的可视化效果,通过定义六个面和对应的坐标点来表示立方体的各个面。 总结起来,VTK中的点、线和面都是用于表示图形对象的基本元素,可以通过设置它们的属性来实现各种形式的可视化效果。无论是单独使用还是组合使用,这些元素都为图形的创建和可视化提供了灵活和多样的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值