gpt4 book ai didi

c++ - 如何在 vtk 中的 3D 表面渲染输出中获取 2D dicom 图像切片的位置

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:08 26 4
gpt4 key购买 nike

我正在做一个 VTK 程序,当我输入一个 2D DICOM 患者图像位置(请引用给定的图像以便更好地理解)时,我需要在3D 表面渲染输出。

对于体积渲染的 3D 图像,这可以通过使用这些函数来实现,即 vtkImageData、vtkImageMapToColors、vtkImage Actor。

enter image description here我的问题是如何在表面渲染输出中做到这一点。有人知道这个概念吗?如果有人知道请回答。如果我的问题不正确或难以理解,请分享您的意见。

为了便于理解,我展示了一张示例图片

考虑我的 3d 输出将如下图所示

enter image description here

当我在文本框中输入图像位置(患者)并单击确定按钮时,相应的切片应显示在 3d 图像中,如下图所示

enter image description here

如果我的问题不明白请告知我被困在这里我什至不知道我的代码是否正确。这是我的代码

    ExtractVOI->SetInput(reader1->GetOutput());//VOI extractor
ExtractVOI->SetVOI(1,0,0,0,1,0);//i have given the Image Orientation(patient) as the SetVOI value


////====CREATE LookUpTable

tableax1->SetTableRange(0.0, 4096.0);
tableax1->SetValueRange(0.0, 1.0);
tableax1->SetSaturationRange(0.0, 0.0);
tableax1->SetRampToSCurve();
tableax1->SetAlphaRange(0.0, 0.08);
tableax1->Build();

//====CREATE TEXTURE

planesourceax1->SetXResolution(1);
planesourceax1->SetYResolution(1);
planesourceax1->SetOrigin(0,0,0);
planesourceax1->SetPoint1(xg , yg,zg);//i have given the value of Image Position(patient) that is taken from a textbox ,as the points

planesourceax1->Update();
vtkSmartPointer<vtkPolyDataMapper> mapax1 = vtkSmartPointer<vtkPolyDataMapper>::New();
mapax1->SetInputConnection(planesourceax1->GetOutputPort());

mapax1->UpdateWholeExtent();
textureax1->SetInputConnection(ExtractVOI->GetOutputPort());
textureax1->InterpolateOn();
textureax1->SetLookupTable(tableax1);
textureax1->UpdateWholeExtent();

//===PASS TO ACTOR
actorax1->SetMapper(mapax1);
actorax1->GetMapper()->SetResolveCoincidentTopologyToPolygonOffset();
actorax1->GetMapper()->SetResolveCoincidentTopologyPolygonOffsetParameters(0.1, -1.0);
actorax1->SetTexture(textureax1);


renderer->AddActor(actorax1);

renderWindow->Render();

但是我没有得到输出

我也试过:

static double axialElements[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };

resliceax1->SetInputConnection(reader->GetOutputPort());
resliceax1->SetOutputDimensionality(2);

vtkSmartPointer<vtkMatrix4x4> reslicematrixax1 = vtkSmartPointer<vtkMatrix4x4>::New();
reslicematrixax1->DeepCopy(axialElements);
resliceax1->SetResliceAxes(reslicematrixax1);
resliceax1->SetResliceAxesOrigin(0.0, 0.0, 0.0);
resliceax1->Update();

extractaxpos1->RemoveAllInputs();
extractaxpos1->SetInputConnection(resliceax1->GetOutputPort());


////====CREATE LUT

tableax1->SetTableRange(0.0, 4096.0);
tableax1->SetValueRange(0.0, 1.0);
tableax1->SetSaturationRange(0.0, 0.0);
tableax1->SetRampToSCurve();
tableax1->SetAlphaRange(0.0, 0.08);
tableax1->Build();

//====CREATE TEXTURE

planesourceax1->SetXResolution(1);
planesourceax1->SetYResolution(1);
planesourceax1->SetOrigin(0,0,0);
planesourceax1->SetPoint1((xval/20 + xval/32),(yval/20 + yval/32),(zval/20 + zval/32));//this is where i put the values ad divided by its tag id(0020,0032)
//planesourceax1->SetPoint2(fBounds[0] , fBounds[3], fBounds[4]);
planesourceax1->Update();
vtkSmartPointer<vtkPolyDataMapper> mapax1 = vtkSmartPointer<vtkPolyDataMapper>::New();
mapax1->SetInputConnection(planesourceax1->GetOutputPort());

mapax1->UpdateWholeExtent();
textureax1->SetInputConnection(extractaxpos1->GetOutputPort());
textureax1->InterpolateOn();
textureax1->SetLookupTable(tableax1);
textureax1->UpdateWholeExtent();

//===PASS TO ACTOR
actorax1->SetMapper(mapax1);
actorax1->GetMapper()->SetResolveCoincidentTopologyToPolygonOffset();
actorax1->GetMapper()->SetResolveCoincidentTopologyPolygonOffsetParameters(0.1, -1.0);
actorax1->SetTexture(textureax1);

resliceax1->SetResliceAxesOrigin(0.0, 0.0, 0.0);
actorax1->SetPosition((xval/20 + xval/32),(yval/20 + yval/32),(zval/20 + zval/32));//I made the same changes here also

planesourceax1->SetOrigin(fBoundsUpdated[0], fBoundsUpdated[2], pDoc->fBounds[4]);
planesourceax1->SetPoint1(fBoundsUpdated[1] , fBoundsUpdated[2], pDoc->fBounds[4]);
planesourceax1->SetPoint2(fBoundsUpdated[0] , fBoundsUpdated[3], pDoc->fBounds[4]);
planesourceax1->Update();

但是不是在slice所在的位置切割,而是在不同的位置切割

最佳答案

如果想知道是什么元素决定切割方向

https://github.com/Kitware/VTK/blob/master/Examples/ImageProcessing/Cxx/ImageSlicing.cxx

请看这个链接

static double axialElements[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };

...

vtkSmartPointer<vtkMatrix4x4> resliceAxes = vtkSmartPointer<vtkMatrix4x4>::New();
resliceAxes->DeepCopy(axialElements);
// Set the point through which to slice
resliceAxes->SetElement(0, 3, 0);
resliceAxes->SetElement(1, 3, 0);
resliceAxes->SetElement(2, 3, 70);

矩阵 4x4 正在设置重新切片方向和 SetElement 决定Reslice origin

这个代码设置选项是Reslice XYimage start at Z = 70

 vtkSmartPointer<vtkImageReslice> reslice = vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputData(m_vtkVolumeImageData);
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
reslice->SetInterpolationModeToLinear();
reslice->Update();

此代码生成 Reslice 数据。结果维度为 2D(平面)如果你设置这个顺序,将 Reslice 数据连接到 vtkImageMapToColors 以绘制 Reslice 图像。

最后,连接 Mapper 和 Actor 以使用 Volume 进行展示。您需要设置 Actor 位置,因为 Reslice Data 可能没有位置信息

如果平面位置没有改变,使用 vtkDataSetMapper 和 vtkActor,而不是 vtkImageActor

或者你只是使用Widget,我推荐 vtkImagePlaneWidget。

它简单而且非常强大。

希望对您有所帮助。

如果你需要完整的代码,请告诉我

关于c++ - 如何在 vtk 中的 3D 表面渲染输出中获取 2D dicom 图像切片的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55120374/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com