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