QVTKWidget控件一般显示二维图片,如果要显示三维图片,并通过鼠标滚轮切换单张图片,则需要加入监听机制,可以自定义一个类来实现所需要的交互方式,该类可以继承于vtkCommand类。
(1)定义鼠标滚轮交互方式,用于显示下一张切片
class vtkNextSliceCallbk : public vtkCommand
{
private:
vtkRenderWindowInteractor *Interactor;
vtkImageViewer2* viewer;
vtkInteractorStyleImage* style;
public:
static vtkNextSliceCallbk *New()
{
return new vtkNextSliceCallbk;
}
vtkNextSliceCallbk()//构造函数
{
this->Interactor = 0;
}
void SetInteractorStyle(vtkInteractorStyleImage* style)
{
this->style = style;
}
void SetInteractor(vtkRenderWindowInteractor *interactor)
{
this->Interactor = interactor;
}
vtkRenderWindowInteractor *GetInteractor()
{
return this->Interactor;
}
void SetViewer(vtkImageViewer2* viewer)
{
this->viewer = viewer;
}
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
int max = viewer->GetSliceMax();//获得最大切片数目,避免翻页超出范围//63,从0开始
int cur = viewer->GetSlice();//获得当前切片
if (eventId == vtkCommand::MouseWheelForwardEvent && cur >= 0)//向前翻页
{
if(cur == 0)//切换到第一张,滚轮继续向前,保持显示第一张切片
viewer->SetSlice(0);
else
viewer->SetSlice(--cur);
viewer->SetSliceOrientationToXY();
Interactor->SetInteractorStyle((vtkInteractorObserver *)style);
}
if (eventId == vtkCommand::MouseWheelBackwardEvent && cur <= max)//向后翻页
{
if(cur == max)//切换到最后一张,滚轮继续向后,保持显示最后一张切片
viewer->SetSlice(max);
else
viewer->SetSlice(++cur);
viewer->SetSliceOrientationToXY();
Interactor->SetInteractorStyle((vtkInteractorObserver *)style);
}
}
};
(2) 读入MHD三维医学图片,通过滚轮切换单张图片,源码如下:
mhdReader = vtkMetaImageReader::New();
mhdReader->SetFileName(inputFileName);
mhdReader->Update();
//统计最大最小灰度值 (或者数据类型),自适应设置窗宽&窗位
//当灰度值高于该范围的最大值时,均以白影显示;而低于该范围时均显示为黑色
dataType = mhdReader->GetDataScalarType();//获得数据类型
imgSize = mhdReader->GetOutput()->GetExtent();//显示图像尺寸
rotate = vtkImageFlip::New();//图像反转
rotate->SetInputConnection(mhdReader->GetOutputPort());
rotate->SetFilteredAxis(1);//y轴反转
originalVtkViewer->SetInputConnection(rotate->GetOutputPort());
//交互
renWinInteractor = vtkRenderWindowInteractor::New();
originalVtkViewer->SetRenderer(originalRenderder);//设置为同一个渲染场景
originalVtkViewer->SetRenderWindow(ui->originalQVTKViewer->GetRenderWindow());
pCall = vtkNextSliceCallbk::New();//实例化自定义类
style = vtkInteractorStyleImage::New();
style->AddObserver(vtkCommand::MouseWheelBackwardEvent, pCall);
style->AddObserver(vtkCommand::MouseWheelForwardEvent, pCall);
renWinInteractor->SetInteractorStyle(style);
renWinInteractor->AddObserver(vtkCommand::MouseWheelBackwardEvent, pCall);//通过交互窗口去监听
renWinInteractor->AddObserver(vtkCommand::MouseWheelForwardEvent, pCall);
pCall->SetInteractorStyle(style);
pCall->SetViewer(originalVtkViewer);
pCall->SetInteractor(renWinInteractor);
ui->originalQVTKViewer->GetRenderWindow()->SetInteractor(renWinInteractor);
originalVtkViewer->SetupInteractor(ui->originalQVTKViewer->GetRenderWindow()->GetInteractor());//设置交互方式
originalVtkViewer->SetSliceOrientationToXY();//设置切片方向
originalVtkViewer->SetColorLevel(128);//窗位
originalVtkViewer->SetColorWindow(256);//窗宽
QVTKWidget控件显示三维图片效果如下: