VTK可视化技术之人类颈动脉血管流动 (Visualizing Blood Flow)

您所在的位置:网站首页 血管三维建模 VTK可视化技术之人类颈动脉血管流动 (Visualizing Blood Flow)

VTK可视化技术之人类颈动脉血管流动 (Visualizing Blood Flow)

2023-12-15 23:40| 来源: 网络整理| 查看: 265

Visualizing Blood Flow

该实例中data包含速度向量vector和速率标量scalar。

利用向量可视化技术创建vector glyph。但是由于存在的points太多,因此需要使用滤波器filter选择合适的点的子集。进而创建向量符号。

采用的滤波器为:vtkThresholdPoints  和 vtkMaskPoints

vtkThresholdPoints 滤波器通过定义阈值,选择大于或者小于阈值的点作为子集。

vtkMaskPoints 滤波器通过OnRation 来实例化points进而选择子集。 如果OnRatio=1,则所有数据点都被选择,如果OnRatio=10,则每10个数据点被选择。可以使均匀选择也可以是随机选择。通过RandomModeOn() 和 RandomModeO方法控制。

选择子集之后在子集中采用vtkGlyph3D滤波器,创建圆锥(其方向代表血流方向,大小和颜色反映速度的大小)。

实现代码和效果图如下:

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main (int argc, char *argv[]) { if (argc < 2) { std::cout SetInputConnection(reader->GetOutputPort()); threshold->ThresholdByUpper(200); vtkSmartPointer mask = vtkSmartPointer::New(); mask->SetInputConnection(threshold->GetOutputPort()); mask->SetOnRatio(5); vtkSmartPointer cone = vtkSmartPointer::New(); cone->SetResolution(11); cone->SetHeight(1); cone->SetRadius(0.25); vtkSmartPointer cones = vtkSmartPointer::New(); cones->SetInputConnection(mask->GetOutputPort()); cones->SetSourceConnection(cone->GetOutputPort()); cones->SetScaleFactor(0.4); cones->SetScaleModeToScaleByVector(); vtkSmartPointer lut = vtkSmartPointer::New(); lut->SetHueRange(.667, 0.0); lut->Build(); double range[2]; cones->Update(); range[0] = cones->GetOutput()->GetPointData()->GetScalars()->GetRange()[0]; range[1] = cones->GetOutput()->GetPointData()->GetScalars()->GetRange()[1]; std::cout SetMapper(vectorMapper); // contours of speed vtkSmartPointer iso = vtkSmartPointer::New(); iso->SetInputConnection(reader->GetOutputPort()); iso->SetValue(0, 175); vtkSmartPointer isoMapper = vtkSmartPointer::New(); isoMapper->SetInputConnection(iso->GetOutputPort()); isoMapper->ScalarVisibilityOff(); vtkSmartPointer isoActor = vtkSmartPointer::New(); isoActor->SetMapper(isoMapper); isoActor->GetProperty()->SetRepresentationToWireframe(); isoActor->GetProperty()->SetOpacity(0.25); // outline vtkSmartPointer outline = vtkSmartPointer::New(); outline->SetInputConnection(reader->GetOutputPort()); vtkSmartPointer outlineMapper = vtkSmartPointer::New(); outlineMapper->SetInputConnection(outline->GetOutputPort()); vtkSmartPointer outlineActor = vtkSmartPointer::New(); outlineActor->SetMapper(outlineMapper); outlineActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData()); // Add the actors to the renderer, set the background and size // ren1->AddActor(outlineActor); ren1->AddActor(vectorActor); ren1->AddActor(isoActor); ren1->SetBackground(colors->GetColor3d("Wheat").GetData()); renWin->SetSize(640, 480); vtkSmartPointer cam1 = vtkSmartPointer::New(); cam1->SetClippingRange(17.4043, 870.216); cam1->SetFocalPoint(136.71, 104.025, 23); cam1->SetPosition(204.747, 258.939, 63.7925); cam1->SetViewUp(-0.102647, -0.210897, 0.972104); cam1->Zoom(1.6); ren1->SetActiveCamera(cam1); // render the image // renWin->Render(); iren->Start(); return EXIT_SUCCESS; }

生成血管速度的streamtubes,可以采用等值面技术。但是streamtubes的起点很那确定。

原因:许多streamers在动脉外边。(数据的测量方法和速度场的分辨率导致),因为数据的分辨率,血液流的边界层不能被捕获,导致在弯道处血液流速的一个分量将 streamtube 指向动脉的外侧。因此很难找到感兴趣结果的streamtube 的起始位置。

解决:源对象 vtkPointSource  和 vtkThresholdPoints

vtkPointSource 生成以指定半径的球体为中心的随机点。只需要找到流管起始点的一个近似位置,然后生成一个随机种子点云。vtkThresholdPoints 用于筛选可能在高流速区域之外生成的点。

主要代码(其余部分与上述代码一样)如下:

// create pipeline // vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(argv[1]); vtkSmartPointer psource = vtkSmartPointer::New(); psource->SetNumberOfPoints(25); psource->SetCenter(133.1, 116.3, 5.0); psource->SetRadius(2.0); vtkSmartPointer threshold = vtkSmartPointer::New(); threshold->SetInputConnection(reader->GetOutputPort()); threshold->ThresholdByUpper(275); vtkSmartPointer streamers = vtkSmartPointer::New(); streamers->SetInputConnection(reader->GetOutputPort()); streamers->SetSourceConnection(psource->GetOutputPort()); // streamers->SetMaximumPropagationUnitToTimeUnit(); streamers->SetMaximumPropagation(100.0); // streamers->SetInitialIntegrationStepUnitToCellLengthUnit(); streamers->SetInitialIntegrationStep(0.2); streamers->SetTerminalSpeed(.01); streamers->Update(); double range[2]; range[0] = streamers->GetOutput()->GetPointData()->GetScalars()->GetRange()[0]; range[1] = streamers->GetOutput()->GetPointData()->GetScalars()->GetRange()[1]; vtkSmartPointer tubes = vtkSmartPointer::New(); tubes->SetInputConnection(streamers->GetOutputPort()); tubes->SetRadius(0.3); tubes->SetNumberOfSides(6); tubes->SetVaryRadius(0); vtkSmartPointer lut = vtkSmartPointer::New(); lut->SetHueRange(.667, 0.0); lut->Build(); vtkSmartPointer streamerMapper = vtkSmartPointer::New(); streamerMapper->SetInputConnection(tubes->GetOutputPort()); streamerMapper->SetScalarRange(range[0], range[1]); streamerMapper->SetLookupTable(lut); vtkSmartPointer streamerActor = vtkSmartPointer::New(); streamerActor->SetMapper(streamerMapper);

实现结果图如下:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3