vtkImageReslice: 三維圖像切片2

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkImageReslice.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkImageActor.h>
#include <QVTKWidget.h>
#include <vtkEventQtSlotConnect.h>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void openFileSlot();
    void callbackSlot(vtkObject* obj, unsigned long eventId, void * clientData, void* callData);
private:
    vtkSmartPointer<vtkRenderer> render;
    vtkSmartPointer<vtkImageReslice> reslice;
    vtkSmartPointer<vtkLookupTable> colorTable;
    vtkSmartPointer<vtkImageMapToColors> colorMap;
    vtkSmartPointer<vtkImageActor> imageActor;
    vtkSmartPointer<vtkEventQtSlotConnect> eventConnector;

private:
    bool isSlice;
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <vtkRenderWindow.h>
#include <vtkPNGReader.h>
#include <vtkMetaImageReader.h>
#include <vtkImageData.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkImageReslice.h>
#include <vtkMatrix4x4.h>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    isSlice = false;
    render = vtkSmartPointer<vtkRenderer>::New();
    connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(openFileSlot()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::openFileSlot()
{
    QString selectFilePath = QFileDialog::getOpenFileName(this, QString("選擇圖像文件"), QString(""), QString("圖像(*.mhd)"));
    if(selectFilePath.isEmpty())
    {
        ui->textBrowser->append("選擇圖像路徑爲空!");
        return ;
    }

    // 原始圖像
    vtkSmartPointer<vtkMetaImageReader> pMhdReader =  vtkSmartPointer<vtkMetaImageReader>::New();
    pMhdReader->SetFileName(selectFilePath.toStdString().c_str());
    pMhdReader->Update();
    ui->textBrowser->append(QString("載入圖像:") + selectFilePath + QString(" 成功 !"));

    int extent[6];
    double spacing[3];
    double origin[3];

    pMhdReader->GetOutput()->GetOrigin(origin);
    pMhdReader->GetOutput()->GetSpacing(spacing);
    pMhdReader->GetOutput()->GetExtent(extent);

    double center[3];
    for(int i = 0; i < 3; ++i)
    {
        center[i] = origin[i] + spacing[i] * (extent[i * 2 + 0] + extent[i * 2 + 1]) / 2.0;
    }

    // 構造切平面
    static double axialElement[16] = {1, 0, 0, 0,
                                      0, 1, 0, 0,
                                      0, 0, 1, 0,
                                      0, 0, 0, 1};

    vtkSmartPointer<vtkMatrix4x4> resliceAxes = vtkSmartPointer<vtkMatrix4x4>::New();
    resliceAxes->DeepCopy(axialElement);

    for(int i = 0; i < 3; ++i)
    {
        resliceAxes->SetElement(i, 3, center[i]);
    }

    // 三維圖像進行切片
    reslice = vtkSmartPointer<vtkImageReslice>::New();
    reslice->SetInputConnection(pMhdReader->GetOutputPort());
    reslice->SetOutputDimensionality(2);
    reslice->SetResliceAxes(resliceAxes);
    reslice->SetInterpolationModeToLinear();
    reslice->Update();

    //    // 進行顏色映射查找表
    //    colorTable = vtkSmartPointer<vtkLookupTable>::New();
    //    colorTable->SetRange(0, 2000);
    //    colorTable->SetValueRange(0.0, 1.0);
    //    colorTable->SetSaturationRange(0.0, 0.0);
    //    colorTable->SetRampToLinear();
    //    colorTable->Build();

    //    // 圖像進行顏色映射
    //    colorMap = vtkSmartPointer<vtkImageMapToColors>::New();
    //    colorMap->SetLookupTable(colorTable);
    //    colorMap->SetInputConnection(reslice->GetOutputPort());
    //    colorMap->Update();


    //    imageActor = vtkSmartPointer<vtkImageActor>::New();
    //    imageActor->SetInputData(colorMap->GetOutput());

    imageActor = vtkSmartPointer<vtkImageActor>::New();
    imageActor->SetInputData(reslice->GetOutput());

    render->AddActor(imageActor);
    ui->qvtkWidget->GetRenderWindow()->AddRenderer(render);

    // 不能在MainWidow的構造函數中
    vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
    ui->qvtkWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);

    eventConnector = vtkSmartPointer<vtkEventQtSlotConnect>::New();
    eventConnector->Connect(ui->qvtkWidget->GetInteractor(),
                            vtkCommand::LeftButtonPressEvent,
                            this,
                            SLOT(callbackSlot(vtkObject* , unsigned long , void *, void*)));

    eventConnector->Connect(ui->qvtkWidget->GetInteractor(),
                            vtkCommand::LeftButtonReleaseEvent,
                            this,
                            SLOT(callbackSlot(vtkObject* , unsigned long , void *, void* )));

    eventConnector->Connect(ui->qvtkWidget->GetInteractor(),
                            vtkCommand::MouseMoveEvent,
                            this,
                            SLOT(callbackSlot(vtkObject* , unsigned long , void *, void*)));

    ui->qvtkWidget->GetRenderWindow()->Render();
}

void MainWindow::callbackSlot(vtkObject* obj, unsigned long eventId, void *clientData, void* callData)
{
    (void)clientData;
    (void)callData;

    vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);

    // 獲取鼠標的位置
    int last_pos[2];
    int cur_pos[2];
    iren->GetLastEventPosition(last_pos);
    iren->GetEventPosition(cur_pos[0], cur_pos[1]);

    if(eventId == vtkCommand::LeftButtonPressEvent)
    {
        qDebug() << "Left Button Press ";
        isSlice = true;
    }
    else if(eventId == vtkCommand::LeftButtonReleaseEvent)
    {
        qDebug() << "Left Button Release ";
        isSlice = false;
    }
    else if(eventId == vtkCommand::MouseMoveEvent)
    {
        qDebug() << "Mouse Move: " << (isSlice ? "Press" : "Release");
        if(isSlice)
        {
            // Increment slice position by deltaY of mouse
            int deltaY = last_pos[1] - cur_pos[1];

            double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
            vtkMatrix4x4 *matrix = reslice->GetResliceAxes();

            // move the center point that we are slicing through
            double point[4];
            double center[4];

            point[0] = 0.0;
            point[1] = 0.0;
            point[2] = sliceSpacing * deltaY;
            point[3] = 1.0;

            matrix->MultiplyPoint(point, center);

            matrix->SetElement(0, 3, center[0]);
            matrix->SetElement(1, 3, center[1]);
            matrix->SetElement(2, 3, center[2]);

            reslice->Update();

            iren->Render();
        }
        else
        {
            vtkSmartPointer<vtkInteractorStyleImage> style = vtkInteractorStyleImage::SafeDownCast(iren->GetInteractorStyle());
            if(style)
            {
                style->OnMouseMove();
            }
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout" stretch="2,5">
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QPushButton" name="pushButton">
        <property name="text">
         <string>選擇圖像</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QTextBrowser" name="textBrowser"/>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QVTKWidget" name="qvtkWidget"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>QVTKWidget</class>
   <extends>QWidget</extends>
   <header>QVTKWidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

按下左鍵,移動鼠標時,切片進行更新(問題,沒有接收道鼠標左鍵釋放的事件消息,不知道爲什麼) 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章