IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> VTK(五)---内窥镜漫游(基于VMTK血管中心线提取) -> 正文阅读

[游戏开发]VTK(五)---内窥镜漫游(基于VMTK血管中心线提取)

在使用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.填补管腔 cappedsurface
    vtkSmartPointer<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.中心线计算 calculate
    vtkSmartPointer<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;

    //setting
    vtkSmartPointer<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 green

    vtkSmartPointer<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;
    }

}


  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-16 22:53:21  更:2022-03-16 22:55:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 17:03:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码