基于vtkImageViewer2的MPR(二):改进
文章目录
- 一、(一)中的问题:
- 1、滚轮向上滚动时,先放大,然后才翻页;没有铺满整个窗口;
- 原因:
- 详细解释:
- 2、先在外面创建窗口,再嵌入到QT渲染窗口中,过程一闪而过,很明显;
- 原因:
- 详细解释:
- 二、完善后的代码:
- 三、显示结果
一、(一)中的问题:
1、滚轮向上滚动时,先放大,然后才翻页;没有铺满整个窗口;
原因:
Render()和 ResetCamera()的调用顺序错误;
详细解释:
在 VTK 中,ResetCamera() 和 Render() 的顺序非常重要:
- ResetCamera():这个函数会重新计算相机参数,使所有可见对象(在这个案例中是图像)能够完全适应渲染窗口。它会根据当前渲染器中的内容调整相机的位置、焦距和视角。
- Render():这个函数执行实际的渲染过程,将场景绘制到渲染窗口中。
如果先调用 Render() 再调用 ResetCamera(),会发生以下情况:
- 第一次 Render() 使用当前的相机设置(可能是默认设置或之前的设置)进行渲染;(小图)
- 然后 ResetCamera() 调整相机参数以适应图像;(自适应铺满,但没有重新Render())
- 但是这次调整后的相机设置不会立即生效,需要再次调用 Render() 才能看到效果
这会导致图像不能正确填充窗口,因为第一次渲染使用的是不合适的相机参数。
2、先在外面创建窗口,再嵌入到QT渲染窗口中,过程一闪而过,很明显;
原因:
SetSliceOrientation()和SetRenderWindow()调用顺序问题;
详细解释:
没有设置RenderWindow,先调用SetSliceOrientation时,vtkImageViewer2内部可能会创建一个默认的渲染窗口,因为它需要一个有效的渲染窗口来设置切片方向。这个默认窗口会作为独立窗口显示,然后当后续调用SetRenderWindow时,才会将其替换为Qt中的窗口。
二、完善后的代码:
QString path = QFileDialog::getExistingDirectory(this,"请选择文件夹路径...","D:/S100/");
//1、读取Dicom文件
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName(path.toStdString().c_str());
reader->Update();vtkSmartPointer<vtkImageData> imageData = reader->GetOutput();
//冠状位
viewX = vtkSmartPointer<vtkImageViewer2>::New();
viewX->SetInputData(imageData);vtkSmartPointer<vtkRenderWindow> renderWindowX = this->ui->openGLWidget_MPR_X->renderWindow();
viewX->SetRenderWindow(renderWindowX);
viewX->SetSliceOrientation(0);//设置切面
viewX->SetColorLevel(25);
viewX->SetColorWindow(3000);
//创建交互器样式
mprInteractorStyleX = vtkSmartPointer<mprVtkInteractorStyleImage>::New();
//把imageView传进去
mprInteractorStyleX->SetImageViewer(viewX);
//创建交互器
vtkSmartPointer<vtkRenderWindowInteractor> interactorX = renderWindowX->GetInteractor();
//一定是先设置;如果后设置,会覆盖之前的设置,style就会失效
viewX->SetupInteractor(interactorX);
//再设置样式
interactorX->SetInteractorStyle(mprInteractorStyleX);
viewX->GetRenderer()->ResetCamera();
viewX->Render();//矢状位
viewY = vtkSmartPointer<vtkImageViewer2>::New();
viewY->SetInputData(imageData);vtkSmartPointer<vtkRenderWindow> renderWindowY = this->ui->openGLWidget_MPR_Y->renderWindow();
viewY->SetRenderWindow(renderWindowY);
viewY->SetSliceOrientation(1);//设置切面
viewY->SetColorLevel(25);
viewY->SetColorWindow(3000);
//创建交互器样式
mprInteractorStyleY = vtkSmartPointer<mprVtkInteractorStyleImage>::New();
//把imageView传进去
mprInteractorStyleY->SetImageViewer(viewY);
//创建交互器
vtkSmartPointer<vtkRenderWindowInteractor> interactorY = renderWindowY->GetInteractor();
//一定是先设置;如果后设置,会覆盖之前的设置,style就会失效
viewY->SetupInteractor(interactorY);
//再设置样式
interactorY->SetInteractorStyle(mprInteractorStyleY);
viewY->GetRenderer()->ResetCamera();
viewY->Render();//横断位
viewZ = vtkSmartPointer<vtkImageViewer2>::New();
viewZ->SetInputData(imageData);
vtkSmartPointer<vtkRenderWindow> renderWindowZ = this->ui->openGLWidget_MPR_Z->renderWindow();
viewZ->SetRenderWindow(renderWindowZ);
viewZ->SetSliceOrientation(2);//设置切面
viewZ->SetColorLevel(25);
viewZ->SetColorWindow(3000);
//创建交互器样式
mprInteractorStyleZ = vtkSmartPointer<mprVtkInteractorStyleImage>::New();
//把imageView传进去
mprInteractorStyleZ->SetImageViewer(viewZ);
//创建交互器
vtkSmartPointer<vtkRenderWindowInteractor> interactorZ = renderWindowZ->GetInteractor();
//一定是先设置;如果后设置,会覆盖之前的设置,style就会失效
viewZ->SetupInteractor(interactorZ);
//再设置样式
interactorZ->SetInteractorStyle(mprInteractorStyleZ);
viewZ->GetRenderer()->ResetCamera();
viewZ->Render();