在使用VMTK血管中心线提取之后,实现内窥镜的漫游:
VTK(四)—VMTK血管中心线提取

本文测试模型:
lumen.stl:
https://github.com/jackyko1991/Vessel-Centerline-Extraction/tree/master/test_data/right

前言

对提取的中心线进行曲线插值,使得路径平滑,并跟随中心线完成内窥镜的漫游。

实现效果:


代码

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)project(EndoRoaming LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Eigen3
find_package( Eigen3 REQUIRED )
# VMTK
find_package( VMTK REQUIRED)
include(${VMTK_USE_FILE})
# ITK
find_package( ITK REQUIRED)
include(${ITK_USE_FILE})
# VTK
find_package( VTK 8.1.2 EXACT REQUIRED)
include(${VTK_USE_FILE})include_directories(${EIGEN3_INCLUDE_DIR})add_executable(EndoRoaming endoroaming.cpp)target_link_libraries(EndoRoaming ${VTK_LIBRARIES})

endoroaming.cpp:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkAxesActor.h>
#include <vtkSTLReader.h>#include <vtkDiscreteMarchingCubes.h>
#include <vtkWindowedSincPolyDataFilter.h>
#include <vtkCleanPolyData.h>
#include <vtkTriangleFilter.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>
#include <vtkIdList.h>
#include <vtkDecimatePro.h>
#include <vtkDoubleArray.h>
#include <vtkParametricSpline.h>
#include <vtkParametricFunctionSource.h>
#include <vtkLODActor.h>
#include <vtkKochanekSpline.h>#include <vtkvmtkCapPolyData.h>
#include <vtkvmtkPolyDataCenterlines.h>#include <Eigen/Core>
#include <Eigen/Eigen>
#include <unistd.h>
#include <iostream>vtkSmartPointer<vtkPolyData> ExtractCenterline(vtkSmartPointer<vtkPolyData> inputSurface) {//1.清理 并 三角化vtkSmartPointer<vtkPolyData> cappedSurface = vtkSmartPointer<vtkPolyData>::New();vtkSmartPointer<vtkCleanPolyData>surfaceCleaner = vtkSmartPointer<vtkCleanPolyData>::New();surfaceCleaner->SetInputData(inputSurface);surfaceCleaner->Update();vtkSmartPointer < vtkTriangleFilter> surfaceTriangulator = vtkSmartPointer<vtkTriangleFilter>::New();surfaceTriangulator->SetInputConnection(surfaceCleaner->GetOutputPort());surfaceTriangulator->PassLinesOff();surfaceTriangulator->PassVertsOff();surfaceTriangulator->Update();cappedSurface->DeepCopy(surfaceTriangulator->GetOutput());//2.填补管腔 cappedsurfacevtkSmartPointer<vtkvmtkCapPolyData> capper = vtkSmartPointer<vtkvmtkCapPolyData>::New();capper->SetInputData(cappedSurface);capper->Update();vtkSmartPointer<vtkIdList> CapCenterIds = vtkSmartPointer<vtkIdList>::New();cappedSurface->DeepCopy(capper->GetOutput());CapCenterIds->DeepCopy(capper->GetCapCenterIds());cout<<"The number of the lumen is:" <<capper->GetCapCenterIds()->GetNumberOfIds()<<endl;//3.设置起始位置//起点vtkSmartPointer<vtkIdList> sourceIds = vtkSmartPointer<vtkIdList>::New();sourceIds->SetNumberOfIds(1);sourceIds->SetId(0, CapCenterIds->GetId(0));vtkSmartPointer<vtkIdList> targetIds = vtkSmartPointer<vtkIdList>::New();//多个目标
//        targetIds->SetNumberOfIds(CapCenterIds->GetNumberOfIds() - 1);
//        for (int i = 1; i < CapCenterIds->GetNumberOfIds(); i++)
//        {//            targetIds->SetId(i - 1, CapCenterIds->GetId(i));
//        }//单个目标targetIds->SetNumberOfIds(1);targetIds->SetId(0, CapCenterIds->GetId(2));//4.中心线计算 calculatevtkSmartPointer<vtkvmtkPolyDataCenterlines> centerlinesFilter = vtkSmartPointer<vtkvmtkPolyDataCenterlines>::New();centerlinesFilter->SetInputData(cappedSurface);centerlinesFilter->SetSourceSeedIds(sourceIds);centerlinesFilter->SetTargetSeedIds(targetIds);centerlinesFilter->SetAppendEndPointsToCenterlines(true);centerlinesFilter->SetCenterlineResampling(true);centerlinesFilter->SetResamplingStepLength(1);centerlinesFilter->SetRadiusArrayName("Radius");centerlinesFilter->SetEdgeArrayName("Edge");centerlinesFilter->SetEdgePCoordArrayName("PCoord");centerlinesFilter->Update();//获取结果vtkSmartPointer<vtkPolyData> output = centerlinesFilter->GetOutput();return output;
}int main(int argc,char**argv)
{if(argc<2){std::cout<<"please input a model\n";return -1;}std::string source = argv[1];vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();reader->SetFileName(source.c_str());reader->Update();// STL 文件vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(reader->GetOutputPort());mapper->Update();vtkSmartPointer<vtkPolyData> data = vtkSmartPointer<vtkPolyData>::New();data->DeepCopy(reader->GetOutput());vtkSmartPointer<vtkPoints> pathpoints =  vtkSmartPointer<vtkPoints>::New();//ExtractCenterline(data);pathpoints->DeepCopy(ExtractCenterline(data)->GetPoints());//-------------------------设置新的引导点---------------------------//-------------------------------------cout<<"The number of points:"<<pathpoints->GetNumberOfPoints()<<endl;//样条曲线拟合vtkNew<vtkKochanekSpline> xSpline;vtkNew<vtkKochanekSpline> ySpline;vtkNew<vtkKochanekSpline> zSpline;vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();spline->SetXSpline(xSpline);spline->SetYSpline(ySpline);spline->SetZSpline(zSpline);spline->SetPoints(pathpoints);vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();functionSource->SetParametricFunction(spline);functionSource->SetUResolution(10 * pathpoints->GetNumberOfPoints());functionSource->SetVResolution(10 * pathpoints->GetNumberOfPoints());functionSource->SetWResolution(10 * pathpoints->GetNumberOfPoints());functionSource->Update();vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();int NumberInsertPoints = 10 * pathpoints->GetNumberOfPoints();double ratioSpeed = 1.0/(NumberInsertPoints-1);for(int i = 0; i < NumberInsertPoints; i++){double u[] = {i*ratioSpeed, 0, 0};double p[3];spline->Evaluate(u, p, nullptr);newPoints->InsertNextPoint(p);}cout<<"The number of new points:"<<newPoints->GetNumberOfPoints()<<endl;//settingvtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();pointMapper->SetInputConnection(functionSource->GetOutputPort());vtkSmartPointer<vtkLODActor> actorPoints = vtkSmartPointer<vtkLODActor>::New();actorPoints->SetMapper(pointMapper);actorPoints->GetProperty()->SetColor(0,1,0);actorPoints->GetProperty()->SetLineWidth(2);//-------------------------------------//-------------------------设置新的引导点---------------------------vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkProperty> property = vtkSmartPointer<vtkProperty>::New();property->SetDiffuseColor(1, 0.49, 0.25);property->SetDiffuse(0.7);property->SetSpecular(0.3);property->SetSpecularPower(20);property->SetOpacity(0.9);  //透明化actor->SetProperty(property);//坐标系vtkSmartPointer<vtkAxesActor> actor2 = vtkSmartPointer<vtkAxesActor>::New(); //三维坐标系actor2->SetPosition(0, 0, 0);actor2->SetTotalLength(100, 100, 100);actor2->SetShaftType(0);actor2->SetAxisLabels(0);vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(actor);renderer->AddActor(actor2);renderer->AddActor(actorPoints);renderer->SetBackground(0.1,0.2,0.4);; // Background color greenvtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(renderer);renderWindow->SetSize(1920,1080);vtkSmartPointer<vtkCamera> aCamera = vtkSmartPointer<vtkCamera>::New();while(true){for(int i=0;i<newPoints->GetNumberOfPoints()-1;i++){double* point = new double[3];double* NextPoint = new double[3];newPoints->GetPoint(i,point);newPoints->GetPoint(i+1,NextPoint);Eigen::Vector3d lastPosition(point[0],point[1],point[2] );Eigen::Vector3d NextPosition(NextPoint[0],NextPoint[1],NextPoint[2] );Eigen::Vector3d focalPoint = NextPosition + (NextPosition - lastPosition)*1.0;aCamera->SetPosition ( lastPosition[0], lastPosition[1], lastPosition[2] );aCamera->SetFocalPoint( focalPoint[0], focalPoint[1], focalPoint[2] );aCamera->SetViewUp ( 0, -1, 0);aCamera->ComputeViewPlaneNormal();renderer->SetActiveCamera(aCamera);renderWindow->Render();usleep(30*1000);}return 0;}}

VTK(五)---内窥镜漫游(基于VMTK血管中心线提取)相关推荐

  1. Steger算法(Line_Gauss)-光条中心线提取(基于Hessian矩阵)

    Steger算法(Line_Gauss)-光条中心线提取(基于Hessian矩阵) 算法背景介绍 Hessian 矩阵与泰勒多项式 关于求t 导数与中心点.亚像素点 高斯函数作用 文献 算法背景介绍 ...

  2. 频谱仪的更改ip_【正点原子FPGA连载】第五十一章 基于FFT IP核的音频频谱仪-摘自【正点原子】开拓者 FPGA 开发指南 (amobbs.com 阿莫电子论坛)...

    本帖最后由 正点原子 于 2020-10-24 15:19 编辑 203429z6c3os33t8albi33.png (66.36 KB) 2019-7-28 15:14 上传 第五十一章 基于FF ...

  3. 图像处理之前景检测(五)之基于样本一致性背景检测(SACON)(主要为代码升级)

    图像处理之前景检测(五)之基于样本一致性背景检测(SACON) SACON(SAmple CONsensus)算法是基于样本一致性的运动目标检测算法.该算法通过对每个像素进行样本一致性判断来判定像素是 ...

  4. GCN实战深入浅出图神经网络第五章:基于Cora数据集的GCN节点分类 代码分析

    GCN实战深入浅出图神经网络第五章:基于Cora数据集的GCN节点分类 代码分析 文章目录 GCN实战深入浅出图神经网络第五章:基于Cora数据集的GCN节点分类 代码分析 SetUp,库声明 数据准 ...

  5. 【Microsoft Azure 的1024种玩法】五十九.基于Azure云平台快速搭建GitLab应用实现代码托管

    [简介] GitLab是由GitLab Inc.开发,一款基于Git的完全整合的软体开发平台,以 Git 作为代码管理工具并实现自托管的 Git 项目仓库,本篇文章主要介绍如何在Azure Virtu ...

  6. 机器学习算法(五):基于企鹅数据集的决策树分类预测

    机器学习算法(五):基于企鹅数据集的决策树分类预测 1 逻决策树的介绍和应用 1.1 决策树的介绍 决策树是一种常见的分类模型,在金融风控.医疗辅助诊断等诸多行业具有较为广泛的应用.决策树的核心思想是 ...

  7. 海思NNIE开发(五):基于Hi3559AV100的FasterRCNN、RFCN、SSD、Yolov2、Yolov3性能综合测评

    系列文章 海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录 海思NNIE开发(二):FasterRCNN在海思NNIE平台上的执行流程(一 ...

  8. 阿里AI攻克心血管识别技术,冠脉中心线提取论文入选国际医学影像会议

    阿里在医疗AI领域取得新进展,继创下肺结节检测.肝结节诊断技术的重大突破后,又攻克了难度系数更高的心血管识别技术. 近日,阿里达摩院机器智能实验室有关冠状动脉中心线提取的论文已被国际顶级医学影像会议M ...

  9. 基于TextRank的关键词提取算法

    基于TextRank的关键词提取算法 前沿 TextRank是一种文本排序算法,是基于著名的网页排序算法PageRank改动而来.在介绍TextRank前,我们先简单介绍下什么是PageRank.另外 ...

  10. matlab模式识别提取特征向量,一种基于小波特征向量提取的手机检测方法与流程...

    本发明涉及到手机检测领域,尤其涉及到一种基于小波特征向量提取的手机检测方法. 背景技术: 随着保密要求的不断提高,很多场合严禁携带手机.录音笔.录像机等电子产品,亟需一种设备可以检测出该类电子产品.目 ...

最新文章

  1. 斯坦福大学 AI100 报告发布:AI 发展速度惊人,但风险也正走进现实
  2. Thread Dump 和Java应用诊断(转)
  3. 【面试锦囊】位运算介绍与经典例题总结
  4. easyui-combobox的取值问题
  5. endnote一打开就自动关闭_word mac版如何彻底删除endnote插件?mac版word移除endnote加载项的方法...
  6. 如何将Outgoing Webhook部署到中国版Azure
  7. java获取classpath以外的路径
  8. python延时队列_如何通过Python实现RabbitMQ延迟队列
  9. CondLaneNet | 使用动态卷积核预测每个车道线实例
  10. 微信小程序 地图功能的实现 map
  11. Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
  12. 【分享】华为总裁任正非谈企业管理:正确的方向来自于妥协
  13. html5豌豆上的公主,豌豆上的公主阅读练习及答案
  14. 20200105每日一句
  15. SendEmail--邮件分发管理系统
  16. 3dmax2018下载3dmax2018下载安装详细教程3dmax2018下载方法
  17. 联发科MTK工程模式(中文对照版本)和测试模式指令
  18. 实例解析云计算的概念
  19. 华为nova5iotg功能使用_华为nova5有OTG功能吗?可以连接U盘和鼠标吗[多图]
  20. Substance Painter TDR issue TDR问题

热门文章

  1. xp桌面上显示计算机名,巧妙还原WinXP快速启动栏的“显示桌面”图标
  2. Git ---- 解决coding:Permission denied(publickey)
  3. oracle10g配置tns,连接Oracle 10g时ORA-12514: TNS: 监听进程不能解析在连接描述符中给出的SID...
  4. SpringBoot的properteis书写[配置对象类型数据、配置数组类型
  5. NTKO word在线文本编辑控件写页眉页脚
  6. C# 正则表达式验证数据类型
  7. 信用体系,生态之魂!——保险科技生态建设
  8. hdu 4609 3-idiots——FFT
  9. linux 文件查找
  10. jQuery增加删除修改tab导航特效