QT&VTK(二) VTK读取所有.vtk文件的属性等相应操作

VTK可以处理的文件类型很多,这里介绍的是.vtk文件的读取,

1. 其中.vtk类型的文件有自己的定义格式,主要分为:几何结构和属性两部分,其中几何结构包括:坐标,拓扑形状的表述。拓扑即组成模型的单元形状,如一维的线,二维的三角形、平行四边形、多边形;三维的四面体、多边形等,根据不同的组成单元,VTK读入时才能知道将单元画成什么样的形状,因此.vtk文件中需说明,如三角形的代号是5,如何在vtk文件中表达,可以参考vtk格式的文档,Bing就有。单元的类型参考介绍VTK基本数据结构

2. 对于不同类型的数据,vtk读入时有不同的函数,如对于规则的四边形,vtk可用vtkstructuredGrid读入,这里参考不同类型的数据集为了通用,我再本项目中选择的vtkPolyData来存储数据。

3. 属性数据由vtkDataArray来表示。属性即单元或点上带有的参数性质,如电势,场强等。从第一类分有:POINT_DATA, CELL_DATA, FIELD_DATA,顾名思义,POINT_DATA就是表明该属性数据定义在点上,如电势,而像单元质量等可能就会被定义在单元上,FIELD_DATA表示既不是在点,又不是在单元上的属性,不常用,这里不再介绍。下图为以上知识点的总结 。

在这里插入图片描述

2.1 属性数据的第二类分级就是:Scalars, Vecotrs, Tensors等 同样是根据名称可以得出,数据分为1维的张量,如电势;3维的矢量,如场强;9维的张量,如张力,注:VTK目前支持对称矩阵的张量。

4. 简单了解.vtk文件的定义后,我们就可以上代码了。有些变量我已经提前声明过了。

string vtkPath='test'
yReader=vtkSmartPointer<vtkDataSetReader>::New();
vtkPath=path.toStdString();
vtkPath.append(".vtk");
Reader->SetFileName(vtkPath.c_str());

Reader->ReadAllScalarsOn();
Reader->ReadAllVectorsOn();
Reader->ReadAllNormalsOn();
Reader->ReadAllTensorsOn();
Reader->ReadAllColorScalarsOn();
Reader->ReadAllTCoordsOn();
Reader->ReadAllFieldsOn();
Reader->GetOutput()->Register(Reader);

//首先读出所有Point和Cell 点属性
DatasetAttributesPoint= vtkSmartPointer <vtkDataSetAttributes> ::New();
DatasetAttributesCell= vtkSmartPointer <vtkDataSetAttributes> ::New();
vtkSmartPointer<vtkDataSet> DataSet=vtkSmartPointer<vtkDataSet> ::New()
DataSet=Reader->GetOutput();
DatasetAttributesPoint=DataSet->GetAttributes(0);// 读取所有POINT点
DatasetAttributesCell=DataSet->GetAttributes(1);// CELL enum编号为1,

// 获取文件中各种类型属性的数量
int numScalars=Reader->GetNumberOfScalarsInFile();
int numVectors=Reader->GetNumberOfVectorsInFile();
int numTensors=Reader->GetNumberOfTensorsInFile();

//读取所有类型属性的名称,并进行存储操作
 for(int i=0;i<numScalars;i++){
        const char* name=Reader->GetScalarsNameInFile(i);
        /*
        ...
        */
 }
 for(int i=0;i<numVectors;i++){
        const char* name=Reader->GetVectorsNameInFile(i);
                /*
        ...
        */
 }
 for(int i=0;i<numTensors;i++){
        const char* name=Reader->GetTensorsNameInFile(i);//
                /*
        ...
        */
 }

//按照名称获取属性
vtkSmartPointer<vtkDataArray> dataSet;
dataSet =DatasetAttributesCell->GetScalars(name.c_str());
dataSet =DatasetAttributesPoint->GetVectors(name.c_str());
dataSet=DatasetAttributesPoint->GetTensors(name.c_str());

vtkSmartPointer<vtkUnstructuredGridReader> MeshReader=vtkSmartPointer<vtkUnstructuredGridReader>::New();
MeshReader->SetFileName(vtkPath.c_str());
MeshReader->Update();
MeshPoints=MeshReader->GetOutput()->GetPoints();
MeshCells=MeshReader->GetOutput()->GetCells();
polyData=vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(MeshPoints);
polyData->SetPolys(MeshCells);

// 以下属性,按照实际情况选择代码
polyData->GetPointData()->SetScalars(dataSet);
polyData->GetPointData()->SetVectors(dataSet);
polyData->GetPointData()->SetTensors(dataSet);

polyData->GetCellData()->SetScalars(dataSet);
polyData->GetCellData()->SetVectors(dataSet);
polyData->GetCellData()->SetTensors(dataSet);

// 以下代码是在Qt中显示vk Widget的代码,所以没有单独的renderwindow.
vMapper->SetInputData(polyData);
vActor->SetMapper(vMapper);
surfaceWidget->GetRenderWindow()->AddRenderer(vRenderer);
vRenderer->AddActor(vActor);
surfaceWidget->update();
surfaceWidget->GetRenderWindow()->AddRenderer(yRenderer);
surfaceWidget->GetRenderWindow()->Render();
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
以下是一个示例代码,可以使用PyQtVTK读取指定的.dcm文件,将其转换为.nii.gz文件,并进行三维可视化: ```python import vtk import numpy as np import SimpleITK as sitk from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QWidget, QVBoxLayout from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("DICOM to NIFTI Converter and Viewer") self.setGeometry(100, 100, 800, 600) self.central_widget = QWidget(self) self.setCentralWidget(self.central_widget) self.vtk_widget = QVTKRenderWindowInteractor(self.central_widget) self.layout = QVBoxLayout(self.central_widget) self.layout.addWidget(self.vtk_widget) self.reader = vtk.vtkDICOMImageReader() self.renderer = vtk.vtkRenderer() self.vtk_widget.GetRenderWindow().AddRenderer(self.renderer) self.renWin = self.vtk_widget.GetRenderWindow() self.interactor = self.renWin.GetInteractor() self.interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera()) self.interactor.SetRenderWindow(self.renWin) self.file_dialog = QFileDialog(self.central_widget) self.file_dialog.setNameFilter("DICOM files (*.dcm)") self.file_dialog.fileSelected.connect(self.load_dicom) self.menu_bar = self.menuBar() self.file_menu = self.menu_bar.addMenu("File") self.open_file_action = self.file_menu.addAction("Open DICOM file") self.open_file_action.triggered.connect(self.file_dialog.exec_) self.convert_to_nifti_action = self.file_menu.addAction("Convert to NIFTI") self.convert_to_nifti_action.triggered.connect(self.convert_to_nifti) def load_dicom(self, filename): self.reader.SetDirectoryName(filename) self.reader.Update() image_data = self.reader.GetOutput() extent = image_data.GetExtent() mapper = vtk.vtkFixedPointVolumeRayCastMapper() mapper.SetInputData(image_data) volume = vtk.vtkVolume() volume.SetMapper(mapper) self.renderer.AddVolume(volume) self.renderer.ResetCamera() self.renWin.Render() def convert_to_nifti(self): filename, _ = self.file_dialog.getSaveFileName(self.central_widget, "Save NIFTI file", "", "NIFTI files (*.nii.gz)") if filename: image_data = self.reader.GetOutput() array = vtk.util.numpy_support.vtk_to_numpy(image_data.GetPointData().GetScalars()) array = np.reshape(array, image_data.GetDimensions(), order='F') sitk_image = sitk.GetImageFromArray(array) sitk_image.SetSpacing(image_data.GetSpacing()) sitk_image.SetOrigin(image_data.GetOrigin()) sitk_image.SetDirection(image_data.GetDirection()) sitk.WriteImage(sitk_image, filename) print("Converted to NIFTI:", filename) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 运行此代码后,将打开一个具有菜单栏的窗口。单击“文件”菜单中的“打开DICOM文件”选项,选择要加载的.dcm文件。加载DICOM文件后,将在窗口中显示三维可视化。单击“文件”菜单中的“转换为NIFTI”选项,选择要将DICOM文件转换为的.nii.gz文件的路径。转换完成后,将在控制台中显示“已转换为NIFTI:”和文件路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值