VTK|加载ply文件数据进行平移+高程渲染

文章目录

  • 将 `.ply` 点云或模型数据进行 Elevation 着色并可视化渲染的完整流程
      • 1. **使用 ElevationFilter 给模型上色(根据 Z 值)**
      • 2. **构造 Jet 风格的 Lookup Table(颜色映射表)**
      • 3. **点变为可渲染的 Vertex 图元**
      • 4. **构造映射器,设置颜色 LUT 和标量范围**
      • 5. **创建并设置 Actor**
      • ⚙️ 6. **清除旧场景并渲染新模型**
      • ✅ 总结整体流程
    • 除了Jet 风格的 Lookup Table(颜色映射表)还有哪些常见的渲染风格
      • 1. **Cool to Warm(冷暖色)**
      • 2. **Rainbow / HSV 彩虹色**
      • 3. **Grayscale(灰度)**
      • 4. **Viridis(Matplotlib 默认)**
      • 5. **Blackbody / Thermal / Fire**
      • 6. **Category / Discrete Colors(分类颜色)**
      • 7. **Custom 自定义色带**

.ply 点云或模型数据进行 Elevation 着色并可视化渲染的完整流程


前置代码 加载ply文件

vtkNew<vtkPLYReader> reader;
reader->SetFileName(filePath.toStdString().c_str());
reader->Update();
polyData = reader->GetOutput();

// 获取包围盒 (Bounds)
double bounds[6];
_poly_data->GetBounds(bounds);
// 计算模型中心
double center[3] = {
  (bounds[0] + bounds[1]) / 2.0,
  (bounds[2] + bounds[3]) / 2.0,
  (bounds[4] + bounds[5]) / 2.0};

// 将整个模型向反方向移动,使其中心点对齐原点
vtkNew<vtkTransform> transform;
transform->Translate(-center[0], -center[1], -center[2]);

1. 使用 ElevationFilter 给模型上色(根据 Z 值)

vtkNew<vtkElevationFilter> elevationFilter;
elevationFilter->SetInputConnection(transformFilter->GetOutputPort());
elevationFilter->SetLowPoint(0, 0, bounds[4] - center[2]);
elevationFilter->SetHighPoint(0, 0, bounds[5] - center[2]);
elevationFilter->Update();
  • vtkElevationFilter 会根据模型每个点在 Z 轴方向的位置 生成一个标量值(类似“高度”)。
  • LowPointHighPoint 设置了 Z 轴范围,这里用了 bounds[4/5] - center[2] 是因为模型已经被平移到以原点为中心。
  • 输出数据中每个点都带上了一个“Z 值标量”,用于后续着色。

2. 构造 Jet 风格的 Lookup Table(颜色映射表)

 // Jet 颜色映射(蓝→青→绿→黄→红)非线性 Jet LUT
    vtkNew<vtkLookupTable> colorLookupTable;
    colorLookupTable->SetNumberOfTableValues(256);
    double scalarRange[2];
    elevationFilter->GetOutput()->GetScalarRange(scalarRange);
    colorLookupTable->SetRange(scalarRange);
    // colorLookupTable->SetRange(-50, 50); // 固定范围,确保色差
    for (int i = 0; i < 256; ++i)
    {
        double t = i / 255.0;

        // 非线性调整 t,使得颜色中段更密集,末端压缩
        double gamma = 0.7; // 越小,中间越突出(类似 CloudCompare),可尝试 0.6 ~ 0.8
        t = std::pow(t, gamma);

        // Jet 调色映射(与 CloudCompare 相似的分布)
        double r = std::clamp(1.5 - std::abs(4.0 * t - 3.0), 0.0, 1.0);
        double g = std::clamp(1.5 - std::abs(4.0 * t - 2.0), 0.0, 1.0);
        double b = std::clamp(1.5 - std::abs(4.0 * t - 1.0), 0.0, 1.0);

        colorLookupTable->SetTableValue(i, r, g, b);
    }
    colorLookupTable->Build();
  • 构造了一个 Jet 风格 的颜色映射(蓝→青→绿→黄→红),类似于 CloudCompare 的配色。
  • 使用了 gamma=0.7 进行非线性压缩,使颜色分布更集中在中间(增加色彩层次感)。
  • 范围固定为 [-50, 50],也就是说,无论模型多高,色差都按这个范围来映射,这是为了防止模型过扁而无法显著看到颜色过渡。

3. 点变为可渲染的 Vertex 图元

auto vertexGlyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexGlyphFilter->AddInputData(elevationFilter->GetOutput());
vertexGlyphFilter->Update();
  • 给模型添加点拓扑(将点转换为可渲染的 vtkVertex),如果省略这一段,纯点云将无法显示。

4. 构造映射器,设置颜色 LUT 和标量范围

auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(vertexGlyphFilter->GetOutputPort());
mapper->SetScalarRange(elevationFilter->GetOutput()->GetScalarRange());
mapper->SetLookupTable(colorLookupTable);
mapper->SetColorModeToMapScalars();
mapper->ScalarVisibilityOn();
mapper->Update();
  • 设置输入数据、颜色映射表。
  • 使用 ElevationFilter 输出的 Z 值作为“标量值”,根据 LUT 显示颜色。
  • SetScalarRange(...) 确保 mapper 知道颜色范围如何对应到颜色表中。

5. 创建并设置 Actor

ply_point_actor_ = vtkSmartPointer<vtkActor>::New();
ply_point_actor_->SetMapper(mapper);
ply_point_actor_->GetProperty()->SetPointSize(point_size_edit_->text().toInt());
  • 使用上面的 Mapper 创建可渲染的 Actor。
  • SetPointSize(...) 设置点大小,读取自 UI 控件(point_size_edit_),用户可调。

⚙️ 6. 清除旧场景并渲染新模型

renderer_->RemoveAllViewProps();           // 移除旧的内容
renderer_->SetBackground(1.0, 1.0, 1.0);    // 设置白色背景
renderer_->AddActor(ply_point_actor_);     // 添加新Actor
addCoordinateAxes();                       // 添加坐标轴
addBoundingBox(transformFilter->GetOutput()); // 添加包围盒
renderer_->ResetCamera();                  // 相机重置
renderWindow_->Render();                   // 执行渲染
m_pScene->update();                        // 通知 UI 更新(Qt)
  • 将新的 actor 放入渲染器中,刷新场景。
  • 添加坐标轴与包围盒用于辅助显示。
  • 调用 ResetCamera() 让摄像头自动对准场景。
  • 渲染窗口刷新,并通过 Qt 通知界面刷新。

✅ 总结整体流程

步骤 说明
① ElevationFilter 为每个点生成 Z 值标量
② LookupTable 创建 Jet 风格 LUT
③ VertexGlyphFilter 点 → vtkVertex,确保可渲染
④ Mapper 设置映射、颜色 LUT、标量范围
⑤ Actor 设置点大小、构建可视化对象
⑥ Renderer 清除旧内容、添加新 Actor、刷新界面

除了Jet 风格的 Lookup Table(颜色映射表)还有哪些常见的渲染风格

除了 Jet 风格(蓝→青→绿→黄→红)之外,VTK 和三维可视化中常见的颜色映射表(Lookup Table, LUT)还有以下几类,每种适合不同的可视化目的:


1. Cool to Warm(冷暖色)

  • 蓝 → 白 → 红(低值冷色,高值暖色)
  • 用途:强调数据中“高/低”对比(如温度、压力)
  • VTK 内置:vtkColorTransferFunction::SetColorSpaceToDiverging() + 两端色设置

2. Rainbow / HSV 彩虹色

  • 类似色相环,覆盖整个色谱
  • 缺点:视觉不连续、对人眼不友好(不推荐用于严肃科学展示)
  • 用途:可用于展示离散类别或艺术可视化
  • VTK:vtkLookupTable::SetHueRange(0.0, 1.0);

3. Grayscale(灰度)

  • ⚫→⚪ 从黑到白

  • 用途:医学图像、形状对比、打印友好

  • 设置方式:

    lut->SetTableValue(i, t, t, t);  // R=G=B
    

4. Viridis(Matplotlib 默认)

  • 深紫 → 蓝 → 青绿 → 黄绿
  • 优点:感知均匀,对色盲友好
  • 用途:科学绘图标准(推荐)
  • 在 VTK 中可手动构造,或从 matplotlib colormap 读取 RGB 值

5. Blackbody / Thermal / Fire

  • ⚪ 类似热红外风格(黑→红→黄→白)
  • 用于:热成像、能量密度可视化
  • VTK:vtkColorTransferFunction::SetColorSpaceToRGB(),然后插值这些颜色

6. Category / Discrete Colors(分类颜色)

  • 固定 N 种颜色(适合整数 label 或分类)
  • 不能用连续 ScalarRange
  • 通常和 vtkUnsignedCharArray 配合使用
  • 示例:红绿蓝紫等分配不同类别

7. Custom 自定义色带

  • 手动设置几个关键色,插值形成 LUT

  • 用法灵活:地形图、高度图、材质图等

  • 例子:

    lut->SetTableValue(0, 0.0, 0.0, 0.5); // 深蓝
    lut->SetTableValue(128, 0.0, 1.0, 0.0); // 绿色
    lut->SetTableValue(255, 1.0, 1.0, 0.0); // 黄色
    

你可能感兴趣的:(VTK,VTK)