Qt VTK交互(上下键滑动图像切片)

Qt VTK交互(上下键滑动图像切片,点击按钮切换三维图像视图)

// main.cpp
#include "qtVtkL01.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qtVtkL01 w;
    w.show();
    return a.exec();
}
//qtVtkL01.h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_qtVtkL01.h"
#include <vtkGenericOpenGLRenderWindow.h>
#include <QFileDialog>
#include <QDir>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkImageViewer2.h>
#include <QVTKWidget.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkEventQtSlotConnect.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>

#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkPolyData.h>
#include <vtkDataSet.h>
#include <vtkPointData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkCubeSource.h>
#include <vtkEventQtSlotConnect.h>

#include <QVTKWidget.h>
#include <QMenu>
#include <QAction>
#include <QPointer>
#include <QVTKOpenGLNativeWidget.h>
#include <QVBoxLayout>
#include <vtkOpenGLRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSmartPointer.h>
#include <QWheelEvent>
#include <vtkCallbackCommand.h>




class qtVtkL01 : public QMainWindow
{
    Q_OBJECT

public:
    qtVtkL01(QWidget *parent = nullptr);
    ~qtVtkL01();


public slots:
    void pushButton_Clicked();


private:
    Ui::qtVtkL01Class ui;

    QVTKOpenGLNativeWidget* vtkWidget;
    //vtkSmartPointer<vtkRenderer> renderer;
    //vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow;
    //vtkSmartPointer<vtkRenderWindow> renderWindow;
    //vtkSmartPointer<vtkRenderWindowInteractor> interactor;
    vtkSmartPointer<vtkImageViewer2> imageViewer;

    int currentSlice; // 当前切片索引
    int minSlice;     // 最小切片索引
    int maxSlice;     // 最大切片索引

    int vision_flag = 1;

};
//qtVtkL01.cpp
#include "qtVtkL01.h"
#include <QVTKOpenGLNativeWidget.h>
#include <vtkMetaImageReader.h>
#include <vtkImageViewer2.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkImageSliceMapper.h>
#include <QSlider>
#include <vtkAutoInit.h> 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);


class myCallback : public vtkCommand
{
public:
    static myCallback* New() {
        return new myCallback;
    }

    // 将
    void setProperty(vtkSmartPointer<vtkImageViewer2> imageViewer, int currentSlice) {

        m_imageViewer = imageViewer;
        m_currentSlice = currentSlice;

        minSlice = 0;
        maxSlice = 200;
    }

    virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) {
        if (eventId == vtkCommand::KeyPressEvent) {
            vtkRenderWindowInteractor* interactor = static_cast<vtkRenderWindowInteractor*>(caller);
            std::string key = interactor->GetKeySym();
            if (key == "Up") {
                if (m_currentSlice < maxSlice) {
                    std::cout << "Up arrow key pressed!  " << m_currentSlice << std::endl;
                    m_currentSlice++;
                    m_imageViewer->SetSlice(m_currentSlice);
                    //m_imageViewer->Render();
                }
                else {
                    m_currentSlice = maxSlice;
                }
            }
            if (key == "Down") {
                if (m_currentSlice > minSlice) {
                    std::cout << "Down arrow key pressed!  " << m_currentSlice << std::endl;
                    m_currentSlice--;
                    m_imageViewer->SetSlice(m_currentSlice);
                    //m_imageViewer->Render();
                }
                else {
                    m_currentSlice = minSlice;
                }
            }
        }
    }

public:
    vtkSmartPointer<vtkImageViewer2> m_imageViewer;

    int m_currentSlice; // 当前切片索引
    int minSlice;     // 最小切片索引
    int maxSlice;     // 最大切片索引
};


qtVtkL01::qtVtkL01(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    setFixedWidth(1000);
    setFixedHeight(700);

    ui.pushButton->setFixedWidth(100);
    ui.pushButton->setFixedHeight(30);

    connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(pushButton_Clicked()));

    // 创建QVTKOpenGLWidget
    ui.vtkWidget->resize(500, 350);
    ui.vtkWidget->move(200, 150);

    // 1- read file
    vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New();
    reader->SetFileName("D:\\Projects\\visualStudio2019\\za\\qtVtkL01\\data\\brain.mhd");
    reader->Update();

    // 创建图像查看器
    imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
    imageViewer->SetInputConnection(reader->GetOutputPort());
    imageViewer->SetColorLevel(500);
    imageViewer->SetColorWindow(2000);
    imageViewer->SetRenderWindow(ui.vtkWidget->GetRenderWindow());
    imageViewer->SetSliceOrientationToXY();
   
    // 获取切片范围
    minSlice = imageViewer->GetSliceMin();
    maxSlice = imageViewer->GetSliceMax();
    currentSlice = minSlice;

    imageViewer->SetSlice(currentSlice);
    imageViewer->Render();

    ui.vtkWidget->GetInteractor()->RemoveAllObservers();

    vtkSmartPointer<myCallback> Callback = vtkSmartPointer<myCallback>::New();
    Callback->setProperty(imageViewer, currentSlice);

    ui.vtkWidget->GetInteractor()->AddObserver(vtkCommand::KeyPressEvent, Callback);
  

    //interactor = ui.vtkWidget->GetRenderWindow()->GetInteractor();
    //vtkSmartPointer<vtkInteractorStyleTrackballCamera> interactorStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    //
    //interactor->SetInteractorStyle(interactorStyle); 
    //interactor->Initialize();

}

qtVtkL01::~qtVtkL01()
{}


void qtVtkL01::pushButton_Clicked() {
    vision_flag++;
    
    if (vision_flag == 1) {
        imageViewer->SetSliceOrientationToXY();
        //imageViewer->Render();
        std::cout << "view xy" << std::endl;
    }
    if (vision_flag == 2) {
        imageViewer->SetSliceOrientationToYZ();
        //imageViewer->Render();
        std::cout << "view yz" << std::endl;
    }
    if (vision_flag == 3) {
        imageViewer->SetSliceOrientationToXZ();
        //imageViewer->Render();
        std::cout << "view xz" << std::endl;
    }
    if (vision_flag == 3) {
        vision_flag = 0;
    }
}

最终的显示效果图如下:
在这里插入图片描述
点击切换视图可以对显示的三维图像数据的视图进行切换,按键盘的上下键可以改变显示的图像切片

注意:
程序中vtkWidget的类型为QVTKOpenGLNativeWidget
并且只使用了vtkImageViewer2 来对图像进行展示。
vtkImageViewer2 内部包括了vtkActor,vtkRender,vtkRenderWindow等对象,不需要我们逐步去构建。
同时,我们也不需要去构建vtkRenderWindowInteractor,因为QVTKOpenGLNativeWidget 会自动为其内部的 vtkRenderWindow 创建一个默认的 vtkRenderWindowInteractor
我们可以直接通过 vtkWidget->GetRenderWindow()->GetInteractor() 获取交互器。
貌似直接使用 vtkWidget->GetInteractor()也可以获取到它的交互器。

一些区别:

imageViewer->SetRenderWindow(ui.vtkWidget->GetRenderWindow());
ui.vtkWidget->SetRenderWindow(imageViewer->GetRenderWindow());

使用下面那行代码,vtk的窗口嵌入不到qt的窗口中。类似下图所示:
在这里插入图片描述
原因是:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值