MIP
MIP(Maximum/Minimum Intensity Projection),最大/最小密度投影重建。
MIP可以较真实地反应组织密度差异,使得血管的异常改变、形态、走形强化;但是只适用于外观形态的显示。
在容积扫描数据中对每条径线上每个像素的最大强度值进行编码并投射成像。MIP的灰阶度反映CT值的相对大小,且比较敏感,即使小的差异也能被检测,如钙化灶、骨骼CT非常高,充盈对比剂的血管同样很高的CT值,但总是低于钙化灶和骨骼,在MIP图像上,其亮度不一样,可区分。
MIP应用价值(最大密度投影重建)
广泛应用于具有相对高密度的组织和结构,如显影的血管、骨骼、肺部肿块以及明显强化的软组织病灶等,对于密度差异甚小的组织结构以及病灶则难以显示。
最小密度投影重建(MinP)
它是在某一平面方向上对所选取的三维组织层块中的最小密度进行投影,主要用于气道的显示。偶尔也用于肝脏增强后肝内扩张胆管的显示。
多张胸部CT图像生成的MIP;
vtkImageSlabReslice
vtkImageSlabReslice类派生自vtkImageReslice类,在切片的基础上,可以设定Slab的厚度,进行多切面的投影叠加。由于vtkImageReslice类继承自vtkThreadedImageAlgorithm类,内部是多线程的,使用方法SetNumberOfThreads()来设置线程个数。vtkImageSlabReslice类以三维图像为输入,沿某一方向产生一个二维的有一定厚度的MPR。
很像vtkimanageslice,reslice轴方向余弦可以通过SetResliceAxes或SetResliceAxesDirectionCosines方法设置。输出间距由SetOutputSpacing控制,输出原点由SetOutputOrigin控制。重新格式化时,由SetBackgroundColor或SetBackgroundLevel控制的位于Volume外部的像素的默认值。SetResliceAxesOrigin()方法还可以用于提供切片将通过的(x,y,z)点。
注意:vtkGPUVolumeRayCastMapper类也有MIP的体渲染方式,具体使用请看官方文档;
接口
投影方式
vtkImageSlabReslice类使用混合函数获取有厚度的切片图像,支持的混合函数包括穿过板的最小强度混合(VTK_IMAGE_SLAB_MIN)、最大强度混合(VTK_IMAGE_SLAB_MAX)和穿过板的平均(平均)强度值(VTK_IMAGE_SLAB_MEAN)。
int BlendMode;
vtkSetMacro(BlendMode, int);
vtkGetMacro(BlendMode, int);
void SetBlendModeToMin() { this->SetBlendMode(VTK_IMAGE_SLAB_MIN); }
void SetBlendModeToMax() { this->SetBlendMode(VTK_IMAGE_SLAB_MAX); }
void SetBlendModeToMean() { this->SetBlendMode(VTK_IMAGE_SLAB_MEAN); }
板间距
板间距是切片层与切片层之间的距离,是在世界坐标系下的真实距离,单位为mm;
板内层个数NumBlendSamplePoints可以由SlabThickness和SlabResolution计算得到,即(2 x (int)(0.5 x SlabThickness/SlabResolution)) + 1;
double SlabResolution;
vtkSetMacro(SlabResolution, double);
vtkGetMacro(SlabResolution, double);
板厚
SlabThickness用来记录板的厚度,必须是非0的正数;
double SlabThickness;
vtkSetMacro(SlabThickness, double);
vtkGetMacro(SlabThickness, double);
切片层个数
NumBlendSamplePoints是指在板内横截面使用的采样点数。如果NumBlendSamplePoints等于1,就相当是vtkImageReslice,一个薄的Reslic切片;NumBlendSamplePoints可以由SlabThickness和SlabResolution计算得到;
int NumBlendSamplePoints;
vtkGetMacro(NumBlendSamplePoints, int);
示例
#include "vtkMetaImageReader.h"
#include "vtkImageData.h"
#include "vtkMatrix4x4.h"
#include "vtkImageReslice.h"
#include "vtkLookupTable.h"
#include "vtkImageMapToColors.h"
#include "vtkImageActor.h"
#include "vtkImageMapper3D.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkImageSlabReslice.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);using namespace std;
int main() {vtkNew<vtkMetaImageReader> reader;reader->SetFileName("D:\\brain.mhd");reader->Update();int extent[6];double spacing[3];double origin[3];reader->GetOutput()->GetExtent(extent);reader->GetOutput()->GetSpacing(spacing);reader->GetOutput()->GetOrigin(origin);double center[3];center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);static double axialElements[16] = {1, 0, 0, 0,0, 1, 0, 0,0, 0, 1, 0,0, 0, 0, 1};vtkNew<vtkMatrix4x4> resliceAxes;resliceAxes->DeepCopy(axialElements);resliceAxes->SetElement(0, 3, center[0]);resliceAxes->SetElement(1, 3, center[1]);resliceAxes->SetElement(2, 3, center[2]);vtkNew<vtkImageSlabReslice> reslice;reslice->SetInputConnection(reader->GetOutputPort());reslice->SetOutputDimensionality(2);reslice->SetResliceAxes(resliceAxes);reslice->SetInterpolationModeToLinear();reslice->SetSlabThickness(200);reslice->SetBlendModeToMax();reslice->Update();vtkNew<vtkLookupTable> colorTable;colorTable->SetRange(0, 1000);colorTable->SetValueRange(0.0, 1.0);colorTable->SetSaturationRange(0.0, 0.0);colorTable->SetRampToLinear();colorTable->Build();vtkNew<vtkImageMapToColors> colorMap;colorMap->SetLookupTable(colorTable);colorMap->SetInputConnection(reslice->GetOutputPort());vtkNew<vtkImageActor> imgActor;imgActor->GetMapper()->SetInputConnection(colorMap->GetOutputPort());vtkNew<vtkRenderer> renderer;renderer->AddActor(imgActor);renderer->SetBackground(1.0, 1.0, 1.0);vtkNew<vtkRenderWindow> renderWindow;renderWindow->AddRenderer(renderer);renderWindow->Render();renderWindow->SetSize(640, 480);renderWindow->SetWindowName("ImageResliceExample");vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;vtkNew<vtkInteractorStyleImage> imagestyle;renderWindowInteractor->SetInteractorStyle(imagestyle);renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return 0;
}
SetSlabThickness使用2.0的效果;
SetSlabThickness使用20.0的效果;
SetSlabThickness使用200.0的效果;
参考资料
1.VTK Examples中MIP和MPR的功能实现与源码分析
2.vtk最大密度投影MIP