- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在做一个 VTK 程序,当我输入一个 2D DICOM 患者图像位置(请引用给定的图像以便更好地理解)时,我需要在3D 表面渲染输出。
对于体积渲染的 3D 图像,这可以通过使用这些函数来实现,即 vtkImageData、vtkImageMapToColors、vtkImage Actor。
我的问题是如何在表面渲染输出中做到这一点。有人知道这个概念吗?如果有人知道请回答。如果我的问题不正确或难以理解,请分享您的意见。
为了便于理解,我展示了一张示例图片
考虑我的 3d 输出将如下图所示
和当我在文本框中输入图像位置(患者)并单击确定按钮时,相应的切片应显示在 3d 图像中,如下图所示
如果我的问题不明白请告知我被困在这里我什至不知道我的代码是否正确。这是我的代码
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/
我正在尝试将一个 DICOM 实例(在我的例子中是一个图像)从一个应用程序发送到一个服务器。但不知何故,它并没有发生。 日志显示某些标签丢失。 那么在 DICOM 关联(在我的例子中是 C-STORE
我所说的方向是指例如从患者的头部到底部或从他的底部到头部。到目前为止,我所看到的胸部 CT 扫描表明,实例编号 1 切片通常是从 body 上部向下的第一个切片,但我不知道这是标准的一部分还是我应该做
我知道单帧和多帧 dicom 图像文件。我想了解电影 dicom 图像,还有其他 dicom 图像格式。 最佳答案 正如您提到的,Alon 在他的评论中提到,DICOM 文件格式支持单帧和多帧像素数据
在处理 DICOM 研究、系列和媒体概念时,我想知道这些值是对所有数据都是唯一的,还是仅对它们所属的患者而言是唯一的。 换句话说;我可以让 2 名患者的研究/系列/sop 实例 uid 对这两名患者具
我有两个 图片 来自同一系列,但两个图像具有相同的 实例编号 6. 有可能吗????根据我的理解,系列实例编号对于该系列中的图像来说是唯一的。所以请帮助我......无论如何,是否可以从模态工作站??
我需要在像 firefox/chrome 这样的浏览器上显示 DICOM 图像。我遇到了这个名为 DWV 的查看器 - https://github.com/ivmartel/dwv . 我想知道是否
我遇到了在私有(private)标签中包含序列的 DICOM 对象;该序列中的每个项目都包含其自己的特定字符集 (0008,0005)。所有特定字符集元素都具有相同的值。 我还发现这些额外的特定字符集
如何识别 dicom 图像是否为压缩格式?还想知道如何读取压缩图像像素数据? 最佳答案 您可以使用命令行工具转储此类信息,例如 gdcminfo: $ gdcminfo 012345.002.050.
是否可以通过读取该研究中文件的 DICOM 头来找到 DICOM 研究中的图像数量? 我正在开发一个 Java 应用程序,它接收来自不同来源的 DICOM 研究。我只是想检查一份研究是否已经完全收到。
我必须从文件夹中选择所有有效的 DICOM 文件。我可以递归地从具有 *.DCM 扩展名的文件夹中选择所有文件。但是任何带有 *.DCM 的文件也会被拾取,并且此类文件不是有效的 DICOM 文件。
我有一堆 DICOM 冠状图像,我使用图像位置(患者)(0020,0032) 标签按正确的顺序对图像进行排序。 然而,该堆栈还包含一个“概述”图像,显示如何从轴向堆栈生成冠状切片 - 请参阅附件。 显
我一直在处理每个大约 4 MB 的 dicom 文件,但我最近收到了一些每个 280 KB 的文件。我不确定这是因为它们来自不同的 CT 扫描仪,还是新的 dicom 在给我之前被压缩了。有没有办法找
为了创建匿名化/去识别化工具,我想从 DICOM 文件中删除/覆盖所有不必要的标签/属性。我在互联网上搜索过,但没有找到 DICOM 文件必须使用哪些标签的明确列表。 我发现有多种类型,类型1是强制的
我有一堆 DICOM 冠状图像,我使用图像位置(患者)(0020,0032) 标签按正确的顺序对图像进行排序。 然而,该堆栈还包含一个“概述”图像,显示如何从轴向堆栈生成冠状切片 - 请参阅附件。 显
我一直在处理每个大约 4 MB 的 dicom 文件,但我最近收到了一些每个 280 KB 的文件。我不确定这是因为它们来自不同的 CT 扫描仪,还是新的 dicom 在给我之前被压缩了。有没有办法找
为了创建匿名化/去识别化工具,我想从 DICOM 文件中删除/覆盖所有不必要的标签/属性。我在互联网上搜索过,但没有找到 DICOM 文件必须使用哪些标签的明确列表。 我发现有多种类型,类型1是强制的
对不起,如果这是非常基本的,我是 DICOM 的新手。我知道 DICOM 文件有多个部分,例如:患者、研究、系列和实例(图像)。 现在要与设备通信,它需要一个传输语法,它告诉通信模式,如 Little
我在解释 DICOM 规范时遇到困难。具体来说,如果我有两个 DICOM 文件,每个文件都表示来自单个 CT 系列(同一研究)的独特 CT 切片。这两个文件都将包含 Patient 模块,因此理论上它
几天以来,我一直在使用 FO-DICOM 处理 DICOM 文件。 我正在使用一组 dicom 文件进行测试,并且我一直在打印“光度解释”和“每像素样本”值,以便更好地了解我正在处理的图像类型。 结果
AFAIK 没有 bool 值表示,我需要在私有(private)标记中指定 bool 值 true/false。 我想到了SH (短字符串),说 TRUE或 FALSE .是否有标准或广泛使用的方法
我是一名优秀的程序员,十分优秀!