CPR曲面重建代码

废话不说,直接上代码:

#include "vtkAutoInit.h"
#include "vtkPolyData.h"
#include "vtkProbeFilter.h"
#include "vtkParametricFunctionSource.h"
#include "vtkParametricSpline.h"
#include "vtkDICOMImageReader.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkWindowLevelLookupTable.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkNamedColors.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageData.h"
#include "vtkDataSetMapper.h"

VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);

// 由曲线生成曲面

vtkPolyData* SweepLine(vtkParametricFunctionSource* line, double direction[3], double distance, int cols)
{
    int rows = line->GetOutput()->GetNumberOfPoints(); //待生成的surface的行数为曲线上点的个数
    double spacing = distance / rows;           //列方向上的spacing
    vtkPolyData* surface = vtkPolyData::New();

    //生成点
    cols += 1;
    int numberOfPoints = rows * cols;       //surface内点的个数
    int numberOfPolys = (rows - 1) * (cols - 1);

    vtkPoints* points = vtkPoints::New();
    points->Allocate(numberOfPoints);
    vtkCellArray* polys = vtkCellArray::New();
    polys->Allocate(numberOfPolys);

    //生成每行每列的点坐标,
    double x[] = { 0.0, 0.0, 0.0 };
    int cnt = 0;

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++) 
        {
            double p[3] = { 0.0,0.0,0.0 };
            line->GetOutput()->GetPoint(row, p);
            x[0] = p[0] + direction[0] * col * spacing;
            x[1] = p[1] + direction[1] * col * spacing;
            x[2] = p[2] + direction[2] * col * spacing;
            points->InsertPoint(cnt, x);
            cnt++;
        }
    }


    //生成四边形
    vtkIdType pts[4] = { 0,0,0,0 };
    for (int row = 0; row < rows - 1; row++)
    {
        for (int col = 0; col < cols - 1; col++)
        {
            pts[0] = col + row * cols;
            pts[1] = pts[0] + 1;
            pts[2] = pts[0] + cols + 1;
            pts[3] = pts[0] + cols;
         //   polys->InsertNextCell(4, pts);   //每临近的四个点构成一个单元
            polys->InsertNextCell(4, pts);
  
        }
    }

    surface->SetPoints(points);
    surface->SetPolys(polys);

    return surface;
}

int main(int argc, char* argv[])
{
    char szInputFile[] = { "D:/imgdata/2013-06-04_dcm" };
    
    vtkDICOMImageReader* reader = vtkDICOMImageReader::New();
    reader->SetDataByteOrderToLittleEndian();
    reader->SetDirectoryName(szInputFile);
    reader->Update();
    int resolution = 100;
    int extent[2] = { 255, 255 };
    double thickness = 1.0;
    double spacing[2] = { 1.0, 1.0 };

    //自定义折线顶点坐标
    vtkPoints* points = vtkPoints::New();
    //(a,b,c,d)其中a表示序号,(b,c,d)表示点的坐标
    points->InsertPoint(0, 1.0, 0.0, 0.0);
    points->InsertPoint(1, 200, 100, 0.0);
    points->InsertPoint(2, 100, 200, 0.0);
    points->InsertPoint(3, 200, 300, 0.0);

    //将点插值逆合成一条曲线
    vtkParametricSpline* spline = vtkParametricSpline::New();
    spline->SetPoints(points);
    vtkParametricFunctionSource* splineFilter = vtkParametricFunctionSource::New();
    splineFilter->SetParametricFunction(spline);
    splineFilter->Update();


    //有曲线生成曲面
    double direction[] = { 0.0, 0.0, 1.0 };
    int distance = 160;
    vtkPolyData* surface = SweepLine(splineFilter, direction, distance, resolution);
    vtkProbeFilter* sampleVolume = vtkProbeFilter::New();
    //这里只能填1,和0,否则曲面要么是一块,要么什么也没有;
    sampleVolume->SetInputConnection(1, reader->GetOutputPort());
    sampleVolume->SetInputData(0, surface);

    //根据数据源的数据范围设置映射表的窗宽窗位
    vtkWindowLevelLookupTable* wlLut = vtkWindowLevelLookupTable::New();
    double range = reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0];
    double level = (reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0]) / 2;
    wlLut->SetWindow(range);
    wlLut->SetLevel(level);

    //创建映射器和角色
    vtkDataSetMapper* mapper = vtkDataSetMapper::New();
    mapper->SetInputConnection(sampleVolume->GetOutputPort());
    mapper->SetLookupTable(wlLut);
    mapper->SetScalarRange(0, 255);

    vtkActor* actor = vtkActor::New();
    actor->SetMapper(mapper);

    //创建渲染器,渲染窗口和交互
    vtkRenderer* ren = vtkRenderer::New();
    vtkRenderWindow* renWin = vtkRenderWindow::New();
    renWin->AddRenderer(ren);
    renWin->SetWindowName("CurvedReformation");

    vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);

    //将角色添加到场景
    ren->AddActor(actor);
    vtkNamedColors* colors = vtkNamedColors::New();
   // ren->SetBackground(colors->GetColor3d("DarkSlateGray"));
    ren->SetBackground(0.4, 0.4, 0.4);

    //设置相机以查看图像
    ren->GetActiveCamera()->SetViewUp(0, 0, 1);
    ren->GetActiveCamera()->SetPosition(0, 0, 0);
    ren->GetActiveCamera()->SetFocalPoint(1, 0, 0);
    ren->ResetCamera();

    //渲染和交互
    renWin->Render();
    iren->Start();

    return 0;
}

效果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件构造 | Design Patterns for Reuse and Maintainability

Design Patterns for Reuse and Maintainability &#xff08;面向可复用性和可维护性的设计模式&#xff09; Open-Closed Principle (OCP) ——对扩展的开放&#xff0c;对修改已有代码的封 Why reusable design patterns A design… …enables flexibility to change …

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇入口差异切换上线IPC管道ATSC任务Impacket套件UI插件

红队内网攻防渗透 1. 内网横向移动1.1 横向移动入口知识点1.1.1、当前被控机处于域内还是域外1.1.1.1 在域内1.1.1.2 不在域内1.1.1.2.1 第一种方法提权到system权限1.1.1.2.2 第二种方法切换用户上线1.1.1.2.3 kerbrute枚举用户1.1.2、当前凭据为明文密码还是HASH1.2 横向移动…

放弃 VS Code:新代码编辑器 Zed 的时代已经到来(附使用感受)

1.Zed 是什么&#xff1f; Zed 由 Nathan Sobo 和一个曾在 GitHub 开发 Atom 和 Tree-sitter 的团队开发。他们的目标是创建一个快速、简单且用户友好的代码编辑器&#xff0c;以提升开发人员的编码体验。以下是关于 Zed 历史的一些关键点&#xff1a; 起源&#xff1a;团队利…

从概念到现实:数字孪生技术在智慧充电站的实践

在电动汽车蓬勃发展的今天&#xff0c;充电基础设施的智能化升级成为了推动新能源汽车产业跃进的关键一环。数字孪生技术&#xff0c;作为智能制造和工业4.0的核心&#xff0c;正在逐渐渗透到智慧充电站的每一个角落——从提高能源效率到增强用户体验&#xff0c;为智慧充电站的…

HarmonyOS NEXT:华为开启全新操作系统时代

在全球科技浪潮的汹涌澎湃中&#xff0c;华为再次以创新者的姿态&#xff0c;引领了一场关于操作系统的革命。HarmonyOS NEXT&#xff0c;这一由华为倾力打造的分布式操作系统&#xff0c;不仅是对现有技术的一次大胆突破&#xff0c;更是对未来智能生活的一次深邃展望。 Harmo…

统信UOS系统忘记登录密码怎么办

在使用统信操作系统UOS的时候有可能会出现忘记密码的情况&#xff0c;当遇到了用户登录密码忘记时如何修改&#xff1f;今天分享一下忘记超级系统管理员Root以及普通密码时的解决方法。 因为UOS系统版本的原因&#xff0c;UOS 1031操作系统取消了单用户更改密码的方法&#xff…

硬核实力再亮,玩出梦想科技发布全球首款安卓系统空间计算机

6月25日&#xff0c;玩出梦想科技在新加坡召开全球新品发布会&#xff0c;正式发布全球首款安卓系统空间计算机——玩出梦想MR&#xff0c;填补了空间计算机在安卓生态的空白。 作为品牌沉淀两年的破晓之作&#xff0c;玩出梦想MR以业内领先软硬件配置&#xff0c;强大自研算法…

Charles抓包工具系列文章(四)-- Rewrite 重写工具

一、背景 这是一款比Map Local/Remote 还强大的工具&#xff0c;更加灵活&#xff0c;体现在以下几点&#xff1a; 重写request报文重写response报文header 字段的增删改query param 字段的增删改重写 body 字段改写http 响应状态status重写host/url/path 从这也可以看出其强…

强化学习-RLHF-PPO入门

一、定义 强化学习微调分类RM模型 数据集格式训练流程Reward 模型训练流程(分类模型&#xff0c;积极为1&#xff0c;消极为0) AutoModelForSequenceClassificationReward 模型训练案例PPO模型训练流程PPO模型训练案例 二、实现 强化学习微调分类 RLHF:基于人类反馈对语言模型…

什么概率密度函数?

首先我们来理解一下什么是连续的随机变量&#xff0c;在此之前&#xff0c;我们要先理解什么是随机变量。所谓随机变量就是在一次随机实验中一组可能的值。比如说抛硬币&#xff0c;我们设正面100&#xff0c;反面200&#xff0c;设随机变量为X&#xff0c;那么X{100,200}。 X是…

Java之多线程的实现与应用

多线程 创建进程方式&#xff1a; &#xff08;1&#xff09;继承Thread类 class Main {public static void main(String[] args) { MyThread01 myThread01new MyThread01(); myThread01.start(); while(true){System.out.println("main方法的run()方法正在运行")…

Vue 3 中处理文件上传和响应式更新

Vue 3 中处理文件上传和响应式更新 一、前言1.创建文件上传组件2.解释代码3.在主应用中使用文件上传组件4.总结 一、前言 在现代 web 开发中&#xff0c;文件上传是一个常见需求。本文将详细介绍如何在 Vue 3 中处理文件上传&#xff0c;并确保上传后的文件列表能够响应式更新…

AI视频教程下载-定制GPT:使用您的数据创建一个定制聊天GPT

Custom GPTs_ Create a Custom ChatGPT with Your Data 构建一个定制的GPT&#xff0c;与您自己的数据进行聊天。添加文档&#xff0c;生成图像&#xff0c;并集成API和Zapier。 这门全面的Udemy课程专为那些渴望学习如何创建自己定制版ChatGPT的人设计&#xff0c;以满足他们…

C++:C与C++混合编程

混合编程 为什么需要混合编程 (1)C有很多优秀成熟项目和库&#xff0c;丢了可惜&#xff0c;重写没必要&#xff0c;C程序里要调用 (2)庞大项目划分后一部分适合用C&#xff0c;一部分适合用C (3)其他情况&#xff0c;如项目组一部分人习惯用C&#xff0c;一部分习惯用C 为什么…

HarmonyOS角落里的知识:“开发应用沉浸式效果”

概述 典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感&#xff0c;从而使用户获得最佳的UI体验。 图1 界面元素示意图 开发应用沉浸式效果主要要考虑如下…

心灵馆咨询系统小程序心理咨询平台聊天咨询

心灵馆咨询系统小程序&#xff1a;解锁你的心灵密码 &#x1f496; 心灵之旅的导航者 在繁忙的现代生活中&#xff0c;我们时常会面临各种压力与困惑。心灵馆咨询系统小程序&#xff0c;如同一位贴心的导航者&#xff0c;引领我们探索内心的世界&#xff0c;寻找真正的自我。 …

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

北大医院副院长李建平:用AI解决临床心肌缺血预测的难点、卡点和痛点

2024年6月14日&#xff0c;第六届北京智源大会在中关村展示中心开幕&#xff0c;海内外的专家学者围绕人工智能关键技术路径和应用场景&#xff0c;展开了精彩演讲与尖峰对话。在「智慧医疗和生物系统&#xff1a;影像、功能与仿真」论坛上&#xff0c;北京大学第一医院副院长、…

[经典]原型资源:蚂蚁金服UI模版部件库

部件库预览链接&#xff1a; https://d3ttsx.axshare.com 支持版本: Axrure RP 8 文件大小: 30MB 文档内容介绍 基本部件&#xff1a;表单样式&#xff1a;12款、数据样式&#xff1a;10款、服务样式&#xff1a;6款、导航&#xff1a;5款、业务组件&#xff1a;7款、 模板…

区块链技术与数字货币

1.起源 ➢中本聪(Satoshi Nakamoto), 2008 ➢比特币:一种点对点的电子现金系统 2.分布式账本技术原理 1.两个核心技术&#xff1a; ➢以链式区块组织账本数据实现账本数据的不可篡改 ➢分布式的可信记账机制 2.共识机制&#xff1a;由谁记账 ➢目的&#xff1a; ⚫ 解…