728x90
이전에 설명한 VTK의 이미지 좌표계와 Dicom 이미지 좌표계는 다르다.
여기에서 한가지 더 참고해야 할 것은 Dicom 이미지는 CT나 MRI 와 같은 장비에서 촬영한 영상이다.
이때 Dicom의 Meta data에는 Image Position Patient (0020, 0032) Tag 정보가 있다.
이는 촬영 장비의 원점에서 Dicom 영상의 좌측상단까지의 위치 값을 나타낸다.
각각의 좌표계에서 보는 이미지를 구성하기 위해서는 각 좌표계별 Transformation 을 구해야한다.
명칭 | 좌표계 원점 | |
CT좌표계 | 장비의 원점 | LPS |
Dicom 좌표계 | 이미지의 좌측상단 | LPS |
Vtk 좌표계 | 이미지의 좌측하단 | i : x axis j : -y axis k : z axis |
각각의 좌표계로의 변환식을 구한다.
VTK to CT 변환 |
VTK to Dicom 변환 |
//이미지 데이터 생성
var simData = SimDataUtils.CreateSimImageData(validSer);
var sliceLoc = simData.SliceInfoList[0].SliceLocation;
var imgBnd = simData.ImageData.GetBounds();
//CT->Dicom 좌표계 변환
var xfmCtToDicom = vtkTransform.New();
xfmCtToDicom.Identity();
xfmCtToDicom.Translate(sliceLoc[0], sliceLoc[1], sliceLoc[2]);
//Dicom->Vtk 좌표계 변환
var xfmDicomToVtk = vtkTransform.New();
xfmDicomToVtk.Identity();
xfmDicomToVtk.Translate(0, imgBnd[3], 0);
xfmDicomToVtk.RotateX(180);
//Vtk->Dicom 좌표계
vtkTransform xfmVtkToDicom = (vtkTransform) xfmDicomToVtk.GetInverse();
//Ct->Vtk 좌표계 변환
var xfmCtToVtk = vtkTransform.New();
xfmCtToVtk.Identity();
xfmCtToVtk.Concatenate(xfmCtToDicom);
xfmCtToVtk.Concatenate(xfmDicomToVtk);
//Vtk->Ct 좌표계
vtkTransform xfmVtkToCt = (vtkTransform)xfmCtToVtk.GetInverse();
var imgMap = vtkImageMapToWindowLevelColors.New();
imgMap.SetInputData(simData.ImageData);
imgMap.SetLevel(280);
imgMap.SetWindow(1600);
imgMap.Update();
vtkImageReslice reslice = vtkImageReslice.New();
reslice.SetInputConnection(imgMap.GetOutputPort());
reslice.SetResliceAxes(xfmVtkToCt.GetMatrix());
// reslice.SetResliceAxes(xfmVtkToDicom.GetMatrix());
reslice.Update();
var mapper = vtkFixedPointVolumeRayCastMapper.New();
mapper.SetInputData(reslice.GetOutput());
var volume = vtkVolume.New();
volume.SetMapper(mapper);
var renWin = vtkRenderWindow.New();
var interactor = vtkRenderWindowInteractor.New();
var renderer = vtkRenderer.New();
interactor.SetRenderWindow(renWin);
renWin.AddRenderer(renderer);
var axesLines = VtkCoordUtils.MakeAxesLines(new double[]{600,600,-600});
foreach (var axesLine in axesLines)
{
renderer.AddActor(axesLine);
}
var axesActor = VtkCoordUtils.MakeAxesActor(new double[] { 200, 200, 200 }, new string[] { "X", "Y", "Z" });
axesActor.SetOrigin(0,0,0);
renderer.AddActor(axesActor);
renderer.AddVolume(volume);
renderer.SetBackground(VtkColorUtils.GetNamedColor3dHandle("Blue"));
renWin.Render();
interactor.Start();
728x90
728x90