利用vtk测量DICOM三维模型的空间物理尺寸

2 篇文章 0 订阅

        在VTK中,专门用于测量距离的类为vtkDistanceWidget和vtkDistanceRepresentation3D,具体的使用方法在VTK源码提供的实例 QtVTKRenderWindows 中说明。

void vtkDistanceRepresentation3D::GetPoint1WorldPosition(double pos[3])
void vtkDistanceRepresentation3D::GetPoint2WorldPosition(double pos[3])

这两个函数获得 pos1 和 pos2 两个端点处的世界坐标,从而可以测量两点之间的世界坐标距离。我们还可以过下面的函数来获取端点 pos1 和 pos2 的屏幕坐标:

void vtkDistanceRepresentation3D::GetPoint1DisplayPosition(double pos[3])
void vtkDistanceRepresentation3D::GetPoint2DisplayPosition(double pos[3])

在实际应用中,我们通常需要测量 3D 实体模型的空间物理尺寸,经过实验发现,我们不需要对vtkDistanceWidget做任何设置,只需要在使用图像读取类(例如vtkDICOMImageReader)读取 dicom 图像的时候,调用 SetDataSpacing() 将像素间距设置为实际距离即可,如果不设置就是读取的 dicom 的像素间距 tag 即(0028,0030) PixelSpacing表示的像素间距,这样测量得到的就是3D模型的空间实际物理尺寸。代码如下:

import vtk
import os

def ShowDicomVtk3D(dicompath):
    render = vtk.vtkRenderer()
    renWin = vtk.vtkRenderWindow()
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)
    renWin.AddRenderer(render)
    renWin.SetSize(512,512)

    style = vtk.vtkInteractorStyleTrackballCamera()
    iren.SetInteractorStyle(style)

    reader = vtk.vtkDICOMImageReader()
    reader.SetDataByteOrderToLittleEndian()
    reader.SetDirectoryName(dicompath)
    reader.SetDataSpacing(3.2, 3.2, 1.5);
    reader.Update()

    contourfilter = vtk.vtkContourFilter()
    contourfilter.SetInputConnection(reader.GetOutputPort())
    contourfilter.SetValue(0, 500)

    normal = vtk.vtkPolyDataNormals()
    normal.SetInputConnection(contourfilter.GetOutputPort())
    normal.SetFeatureAngle(60)

    conMapper = vtk.vtkPolyDataMapper()
    conMapper.SetInputConnection(normal.GetOutputPort())
    conMapper.ScalarVisibilityOff()

    conActor = vtk.vtkActor()
    conActor.SetMapper(conMapper)
    render.AddActor(conActor)

	# 测量3D实体大小
    distanceWidget = vtk.vtkDistanceWidget();
    distanceWidget.SetInteractor(iren);
    representation = vtk.vtkDistanceRepresentation3D();
    distanceWidget.SetRepresentation(representation);
    distanceWidget.SetPriority(0.9);
    representation.GetLineProperty().SetColor(0, 1, 0);  # 绿色
    representation.GetLabelProperty().SetColor(1, 0, 0); # 红色
    distanceWidget.GetRepresentation().SetLabelFormat("%-#6.2f mm");
    distanceWidget.ManagesCursorOn();
    distanceWidget.On();
    
    # 相机设置
    camera = vtk.vtkCamera()
    camera.SetViewUp(0, 0, -1)
    camera.SetPosition(0, 1, 0)
    camera.SetFocalPoint(0, 0, 0)
    camera.ComputeViewPlaneNormal()
    camera.Dolly(1.5)
    render.SetActiveCamera(camera)
    render.ResetCamera()

    iren.Initialize()
    iren.Start()


if __name__ == '__main__':
    ShowDicomVtk3D("E://data//01//CT1.25mm")

结果示例:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值