3D医学影像开发入门<二>:VS2019+Qt5.15.2+VTK9.3.1编译及环境配置

news2024/11/25 23:27:28

  
  VTK(Visualization Toolkit)是一个开源的、跨平台的三维可视化开发库,用于处理和可视化三维数据。它提供了一系列算法和工具,用于创建、操作和渲染复杂的三维图形,并支持多种数据表示方式,包括点、线、面、体等。VTK提供了一套高效的算法,用于可视化医学图像、流体动力学模拟、地理信息系统等领域的数据。

1、VTK源码下载

  源码下载地址:https://vtk.org/download/
在这里插入图片描述

  将VTK-9.3.1.tar.gz ,VTKData-9.3.1.tar.gz,VTKLargeData-9.3.1.tar.gz解压到同一目录,并创建build和SDK文件夹。

在这里插入图片描述

在这里插入图片描述

2、CMake设置

  打开CMake-gui进行设置:
在这里插入图片描述
  开启支持Qt编译;电脑上会自动找到对应的Qt路径(Qt已经在电脑环境变量添加过路径)。

在这里插入图片描述

在这里插入图片描述

点击“config”按钮,没有错误提示后点击“Generate”按钮,最后点击“open project”按钮打开VS工程。

在这里插入图片描述

3、VS编译

  点击Open project 按钮打开VS项目工程,然后先选择 ALL_BUILD进行生成,随后选择INSTALL进行sdk整理。

在这里插入图片描述
在这里插入图片描述
编译后的VTK sdk如下所示:
在这里插入图片描述

4、示例demo

  编译完成后我们来验证一下VTK编译的是否正确可用。此处可以参考VTK提供的示例代码。我们用了Qt+VTK来进行验证。https://examples.vtk.org/site/。

在这里插入图片描述

4.1 演示效果

  演示效果如下图:

在这里插入图片描述

4.2 源码

#include <QtCore/QCoreApplication>

#include <QVTKOpenGLNativeWidget.h>
#include <vtkActor.h>
#include <vtkDataSetMapper.h>
#include <vtkDoubleArray.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPointData.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>

#include <QApplication>
#include <QDockWidget>
#include <QGridLayout>
#include <QLabel>
#include <QMainWindow>
#include <QPointer>
#include <QPushButton>
#include <QVBoxLayout>

#include <cmath>
#include <cstdlib>
#include <random>

namespace {
    /**
     * Deform the sphere source using a random amplitude and modes and render it in
     * the window
     *
     * @param sphere the original sphere source
     * @param mapper the mapper for the scene
     * @param window the window to render to
     * @param randEng the random number generator engine
     */
    void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,
        vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng);
} // namespace

int main(int argc, char* argv[])
{
    QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());

    QApplication app(argc, argv);

    // Main window.
    QMainWindow mainWindow;
    mainWindow.resize(1200, 900);

    // Control area.
    QDockWidget controlDock;
    mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock);

    QLabel controlDockTitle("Control Dock");
    controlDockTitle.setMargin(20);
    controlDock.setTitleBarWidget(&controlDockTitle);

    QPointer<QVBoxLayout> dockLayout = new QVBoxLayout();
    QWidget layoutContainer;
    layoutContainer.setLayout(dockLayout);
    controlDock.setWidget(&layoutContainer);

    QPushButton randomizeButton;
    randomizeButton.setText("Randomize");
    dockLayout->addWidget(&randomizeButton);

    // Render area.
    QPointer<QVTKOpenGLNativeWidget> vtkRenderWidget =
        new QVTKOpenGLNativeWidget();
    mainWindow.setCentralWidget(vtkRenderWidget);

    // VTK part.
    vtkNew<vtkGenericOpenGLRenderWindow> window;
    vtkRenderWidget->setRenderWindow(window.Get());

    vtkNew<vtkSphereSource> sphere;
    sphere->SetRadius(1.0);
    sphere->SetThetaResolution(100);
    sphere->SetPhiResolution(100);

    vtkNew<vtkDataSetMapper> mapper;
    mapper->SetInputConnection(sphere->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetEdgeVisibility(true);
    actor->GetProperty()->SetRepresentationToSurface();

    vtkNew<vtkRenderer> renderer;
    renderer->AddActor(actor);

    window->AddRenderer(renderer);

    // Setup initial status.
    std::mt19937 randEng(0);
    ::Randomize(sphere, mapper, window, randEng);

    // connect the buttons
    QObject::connect(&randomizeButton, &QPushButton::released,
        [&]() { ::Randomize(sphere, mapper, window, randEng); });

    mainWindow.show();

    return app.exec();
}

namespace {
    void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,
        vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng)
    {
        // Generate randomness.
        double randAmp = 0.2 + ((randEng() % 1000) / 1000.0) * 0.2;
        double randThetaFreq = 1.0 + (randEng() % 9);
        double randPhiFreq = 1.0 + (randEng() % 9);

        // Extract and prepare data.
        sphere->Update();
        vtkSmartPointer<vtkPolyData> newSphere;
        newSphere.TakeReference(sphere->GetOutput()->NewInstance());
        newSphere->DeepCopy(sphere->GetOutput());
        vtkNew<vtkDoubleArray> height;
        height->SetName("Height");
        height->SetNumberOfComponents(1);
        height->SetNumberOfTuples(newSphere->GetNumberOfPoints());
        newSphere->GetPointData()->AddArray(height);

        // Deform the sphere.
        for (int iP = 0; iP < newSphere->GetNumberOfPoints(); iP++)
        {
            double pt[3] = { 0.0 };
            newSphere->GetPoint(iP, pt);
            double theta = std::atan2(pt[1], pt[0]);
            double phi =
                std::atan2(pt[2], std::sqrt(std::pow(pt[0], 2) + std::pow(pt[1], 2)));
            double thisAmp =
                randAmp * std::cos(randThetaFreq * theta) * std::sin(randPhiFreq * phi);
            height->SetValue(iP, thisAmp);
            pt[0] += thisAmp * std::cos(theta) * std::cos(phi);
            pt[1] += thisAmp * std::sin(theta) * std::cos(phi);
            pt[2] += thisAmp * std::sin(phi);
            newSphere->GetPoints()->SetPoint(iP, pt);
        }
        newSphere->GetPointData()->SetScalars(height);

        // Reconfigure the pipeline to take the new deformed sphere.
        mapper->SetInputDataObject(newSphere);
        mapper->SetScalarModeToUsePointData();
        mapper->ColorByArrayComponent("Height", 0);
        window->Render();
    }
} // namespace

4.3 项目属性设定

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

vtkGUISupportQt-9.3d.lib
vtkRenderingCore-9.3d.lib
vtkRenderingOpenGL2-9.3d.lib
vtkCommonCore-9.3d.lib
vtkCommonDataModel-9.3d.lib
vtkCommonExecutionModel-9.3d.lib
vtkFiltersCore-9.3d.lib
vtkFiltersSources-9.3d.lib
vtksys-9.3d.lib

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2211975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

传值与传址

目录 前言1.基础2.实际计算 前言 这是在软考中软件设计师有关的考点&#xff0c;关于程序设计基础——传值与传址 1.基础 传值和传址是两种不同的参数传递方式。 传值&#xff08;传递值&#xff09;是指将参数的副本传递给函数或方法。在函数或方法中对参数的任何修改不会影…

WebGL 入门学习

1. WebGL是什么&#xff1f; WebGL&#xff08;Web Graphics Library&#xff09;是一种JavaScript API&#xff0c;它允许你在不需要安装任何额外插件的情况下&#xff0c;直接在浏览器中渲染高性能的2D和3D图形。WebGL利用了用户的图形处理单元&#xff08;GPU&#xff09;来…

竹壳天气时钟(二)第二阶段任务已完成

一、简介 准备用基于esp8266的nodemcu开发板做一个天气时钟。 一步一步记录代码编写过程。 竹壳天气时钟 Bamboo shell weather clock 使用基于esp8266的NodeMCU制作。 计划用竹子做最后成品的外壳&#xff0c;所以才有了这个名称。 第一阶段任务&#xff1a; 1.开启混合模式&…

【吊打面试官系列-微服务面试题】单片,SOA 和微服务架构有什么区别?

大家好&#xff0c;我是锋哥。今天分享关于【单片&#xff0c;SOA 和微服务架构有什么区别&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 单片&#xff0c;SOA 和微服务架构有什么区别&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 …

基于SSM框架学籍管理系统的设计与实现

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;乡下小哥编程。回复 Java全套视频教程 或 前端全套视频教…

DataStore存储数据+加上加密

如果没有使用SP来存储数据&#xff0c;而是用datastore的话 但是datastore存储是个文件&#xff0c;所以我们需要再加密。 先展示没有加密的存储方式&#xff0c;然后再结合上一节的加密&#xff0c;再将存储的数据进行加密 使用datastore存储数据 添加依赖库 implementat…

心血之作!独家原创改进班翠鸟优化算法IPKO!2024年新算法!效果极佳!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ ​历经数月&#xff0c;今天又给小伙伴们带了一期独…

IRP学习理解

IRP是Windows内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时&#xff0c;应用程序会发出I/O请求&#xff0c;操作系统将相应的I/O请求转换成相应的IRP&#xff0c;不同的IRP会根据类型被分派到不同的派遣例程中进行处理。 irp相当于R3下的消息&#xff0c…

【文档智能】文本文字识别、公式识别、表格文字识别核心算法及思路及实践-DBNet、CRNN、TrOCR

前言 OCR技术作为文档智能解析链路中的核心组件之一&#xff0c;贯穿整个技术链路&#xff0c;包括&#xff1a;文字识别、表格文字识别、公式识别&#xff0c;参看下面这张架构图&#xff1a; 前期介绍了很多关于文档智能解析相关核心技术及思路&#xff0c;本着连载的目的&a…

特斯拉“We, Robot“发布会:Robotaxi亮相,马斯克兑现承诺

在加利福尼亚州伯班克的华纳兄弟电影制片厂&#xff0c;特斯拉举办了以"We&#xff0c; Robot"为主题的发布会&#xff0c;这场活动吸引了全球科技爱好者的目光。特斯拉在此次发布会上展示了其在自动驾驶领域的最新突破&#xff0c;特别是公司CEO埃隆马斯克多年来承诺…

麒麟桌面版v10 SP1以docker方式安装达梦数据库

安装docker 0.切换root用户&#xff08;可以不切换&#xff0c;但要注意权限问题&#xff0c;我是用root&#xff09; ymym-pc:~/桌面$ whoami ym ymym-pc:~/桌面$ sudo -i rootym-pc:~# whoami root rootym-pc:~# 1.查看系统版本 [rootlocalhost opt]# cat /etc/os-release…

AI知识库如何提升服装电商的运营效率

随着人工智能技术的飞速发展&#xff0c;AI知识库在服装电商领域的应用日益广泛。AI知识库作为一个集成了海量数据、通过高级算法进行智能分析和处理的信息系统&#xff0c;正在深刻改变服装电商的运营模式和效率。本文将详细阐述AI知识库在商品信息管理、库存管理、订单处理等…

C语言题目练习4

这一篇博客继续在算法题的海洋里面遨游~ 链表的中间结点 链表的中间结点&#xff1a; https://leetcode.cn/problems/middle-of-the-linked-list/description/ 这个题我们可以怎么办呢&#xff1f;这里依然提供两个思路 思路1 既然是中间结点我们是不是可以直接第一次循环求…

MySQL从入门到跑路

SQL语言 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理和操作关系数据库的一种标准编程语言。 SQL分类&#xff1a; DDL(Data Definition Language)&#xff1a;数据定义语言&#xff0c;用于操作数据库、表、字段&#xff0c…

天气API接口调用

天气API接口&#xff1a; 天气API接口是一种用于获取实时或预报天气信息的应用程序编程接口&#xff08;API&#xff09;。开发者可以使用这种接口在他们的应用程序或网站上集成天气查询功能&#xff0c;比如查询某个地区的当前温度、降水量、风速等数据。 通常&#xff0c;你…

Django ORM 进行基础 CRUD 操作(创建、读取、更新、删除)

Django ORM 进行基础 CRUD 操作&#xff08;创建、读取、更新、删除&#xff09; Django 是一个流行的 Python web 框架&#xff0c;提供了很多实用的功能来帮助开发者快速构建 web 应用程序。Django 的 ORM&#xff08;Object-Relational Mapping&#xff09;是其强大的数据库…

Java_ EE (网络编程)

网络编程基本概念: 计算机网络计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统。从其…

【C++算法】双指针

目录 一、快乐数&#xff1a; 二、有效三角形的个数&#xff1a; 三、盛最多水的容器&#xff1a; 四、复写0&#xff1a; 五、三数之和&#xff1a; 总结&#xff1a; 一、快乐数&#xff1a; 题目出处&#xff1a; 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09…

spring task的使用场景

spring task 简介 spring task 是spring自带的任务调度框架按照约定的时间执行某个方法的工具&#xff0c;类似于闹钟 应用场景 cron表达式 周和日两者必定有一个是问号 简单案例

基于java的企业车辆管理系统设计与实现(论文+源码)-kaic

摘 要 随着经济的日益增长,车辆作为最重要的交通工具,在企事业单位中得以普及,单位的车辆数目已经远远不止简单的几辆,与此同时就产生了车辆资源的合理分配使用问题。现有的车辆管理系统存在着不足之处&#xff0c;例如系统不够稳定&#xff0c;功能不够全面。因此&#xff0c…