【VTK】VTK+QT打开dicom图像并实时显⽰⿏标坐标位置和
像素值
最近在学习VTK+QT+C++,学习之路真是艰苦。不过总算是努⼒就有收获,回到正题。
⾸先,在QT中放⼊QVTKWidget插件,这个之前⼜说,不赘述。新建⼀个QT应⽤程序,有三个可编辑的⽂件,即、⼯程名.h、⼯程名.cxx。main⽂件⼏乎不需要编辑。
//
#include <QApplication>
#if QT_VERSION < 0x050000
#include <QCleanlooksStyle>
#endif
#include "SimpleView.h"
extern int qInitResources_icons();
int main( int argc, char** argv )
{
// QT Stuff
QApplication app( argc, argv );
#if QT_VERSION >= 0x050000
QApplication::setStyle("fusion");
#else
include和contain
QApplication::setStyle(new QCleanlooksStyle);
#endif
qInitResources_icons();
SimpleView mySimpleView;
mySimpleView.show();
();
}
接下来是⼯程⽂件,我的是SimpleView.h
//SimpleView.h
#ifndef SimpleView_H
#define SimpleView_H
#include "vtkSmartPointer.h"    // Required for smart pointer internal ivars.
#include <QMainWindow>
#include "ui_SimpleView.h"
#include <QFileDialog>
#include <QDir>
#include <qstring.h>
#include <qlineedit.h>
#include <QPushButton>
#include <vtkDataObjectToTable.h>
#include <vtkElevationFilter.h>
#include <vtkPolyDataMapper.h>
//#include <vtkQtTableView.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkVectorText.h>
#include <QtWidgets/QApplication>
#include "vtkImageViewer2.h"
#include "vtkInteractorStyleImage.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageActor.h"
#include "vtkDICOMImageReader.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "string"
#include "vtkCommand.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
#include "vtkPropPicker.h"
#include "vtkCornerAnnotation.h"
#include "vtkAssemblyPath.h"
#include <vtkEventQtSlotConnect.h>
#include <vtkImageNoiseSource.h>
#include <vtkImageCast.h>
#include <QVTKWidget.h>
class Ui_SimpleView;
class vtkImageViewer2;
class vtkRenderer;
class vtkEventQtSlotConnect;
class vtkObject;
class vtkCommand;
class SimpleView : public QMainWindow,public Ui::SimpleView
{
Q_OBJECT
public:
// Constructor/Destructor
SimpleView();
~SimpleView();
public:
/
/void vtkValueMessageTemplate(vtkImageData* image, int* position);
public slots:
virtual void slotOpenFile();
virtual void slotExit();
//响应⿏标移动的消息,实时输出⿏标的当前位置
void updateCoords(void);
private:
//Members
vtkSmartPointer<vtkImageViewer2>            myViewer;
vtkSmartPointer<vtkRenderer>                myRender;
vtkSmartPointer<vtkDICOMImageReader>        reader;
vtkSmartPointer<vtkPropPicker>              propPicker;
vtkPropPicker*              Picker;          // Pointer to the picker
vtkCornerAnnotation*        Annotation;      // Pointer to the annotation  vtkSmartPointer<vtkEventQtSlotConnect>      m_Connections;
// Designer form
Ui_SimpleView *ui;
};
#endif // SimpleView_H
最后是,重要的实现都在这⾥
#include "ui_SimpleView.h"
#include "SimpleView.h"
#include "vtkSmartPointer.h"
#include <vtkMath.h>
#include <typeinfo>
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
// Constructor
SimpleView::SimpleView()
{
this->ui = new Ui_SimpleView;
this->ui->setupUi(this);
// vtkImageViewer2 全局变量
this->myViewer = vtkSmartPointer<vtkImageViewer2>::New();
this->myRender = vtkSmartPointer<vtkRenderer>::New();
this->reader = vtkSmartPointer<vtkDICOMImageReader>::New();
this->m_Connections = vtkSmartPointer<vtkEventQtSlotConnect>::New();
this->Picker = vtkSmartPointer<vtkPropPicker>::New();;
this->Annotation = vtkSmartPointer<vtkCornerAnnotation>::New();
this->propPicker = vtkSmartPointer<vtkPropPicker>::New();
//设置qvtkWidget的渲染器
this->ui->qvtkWidget->GetRenderWindow()->AddRenderer(this->myRender);
// Set up action signals and slots
connect(this->ui->actionOpenFile, SIGNAL(triggered()), this, SLOT(slotOpenFile()));
connect(this->ui->actionExit, SIGNAL(triggered()), this, SLOT(slotExit()));
/
/>>>>>>>>>>>>>>>>
this->m_Connections->Connect(ui->qvtkWidget->GetRenderWindow()->GetInteractor(),
vtkCommand::MouseMoveEvent, this, SLOT(updateCoords()));
//>>>>>>>>>>>>>>>> };
//Destructor
SimpleView::~SimpleView()
{
// The smart pointers should clean up for up
}
void SimpleView::slotOpenFile(void)
{
QString FileInstruction;// 新建⼀个QString对象
FileInstruction = "Image Files(*.dcm);;ALL(*.*)";
QDir FileDir; //使⽤相对或绝对路径指向⽂件/⽬录
//this指定⽗组件
QString fileName = QFileDialog::getOpenFileName(this,"", FileDir.absolutePath(), FileInstruction);
// 判断路径是否正确
if (fileName.isEmpty() == true)
{
cout << "error path" << endl;
return;
}
/
/Display path
//Display path
QFileInfo OpenFileInfo;
OpenFileInfo = QFileInfo(fileName);
QString OpenFilePath = OpenFileInfo.filePath();
//路径名显⽰在lineEdit中
ui->lineEdit->setText(OpenFilePath);
//Support Chinese path
QByteArray ba = Local8Bit();
const char* fileName_str = ba.data();
reader->SetFileName(fileName_str);// Set the filename for the file to read.
reader->Update();
// Visualize 将reader的输出作为myViewer的输⼊
myViewer->SetInputConnection(reader->GetOutputPort());
myViewer->UpdateDisplayExtent();
// Window是QT的,render是vtk的,设置myViewer与渲染器myRenderer的关联
myViewer->SetRenderWindow(ui->qvtkWidget->GetRenderWindow());
myViewer->SetRenderer(myRender);
//⽤QT界⾯⾥的interactor响应⿏标事件
myViewer->SetupInteractor(ui->qvtkWidget->GetRenderWindow()->GetInteractor());
myViewer->SetSliceOrientationToXY(); //默认就是这个⽅向的
//插值
myRender->ResetCamera();
// Set background color 设置的是背景,使⽤创建的myRender⽽不是获取myViewer的render(已关联) myRender->GradientBackgroundOn();
myRender->SetBackground(0.6, 0.6, 0.5);
myRender->SetBackground2(0.3, 0.3, 0.2); //渐变背景渲染
myRender->DrawOn();
ui->qvtkWidget->GetRenderWindow()->Render();
}
// Template for image value reading
template<typename T> // 模板,初始化时才知道其类型
// 形参为图像,位置和信息
void vtkValueMessageTemplate(vtkImageData* image, int* position, std::string& message)
{
T* tuple = ((T*)image->GetScalarPointer(position)); // 返回⼀个指向image的位置指针
int components = image->GetNumberOfScalarComponents(); // 获取点的标量分量的数量
for (int c = 0; c < components; ++c)
{
//cout << "pixel_value: " << pixel_value << endl;
message += vtkVariant(tuple[c]).ToString();
if (c != (components - 1))
{
message += ", ";
}
}
//cout << "pixel value: " << message.c_str() << endl;
}
void SimpleView::updateCoords(void)
{
// Picker to pick pixels
this->propPicker->PickFromListOn();
// Give the picker a prop to pick
vtkImageActor* imageActor = this->myViewer->GetImageActor();
propPicker->AddPickList(imageActor);
// disable interpolation, so we can see each pixel
/
/ disable interpolation, so we can see each pixel
imageActor->InterpolateOff();
// Annotate the image with window/level and mouse over pixel information
vtkSmartPointer<vtkCornerAnnotation> cornerAnnotation =
vtkSmartPointer<vtkCornerAnnotation>::New();
cornerAnnotation->SetLinearFontScaleFactor(2);
cornerAnnotation->SetNonlinearFontScaleFactor(1);
cornerAnnotation->SetMaximumFontSize(20);
cornerAnnotation->SetText(0, "Off Image");
cornerAnnotation->SetText(3, "<window>\n<level>");
//cornerAnnotation->GetTextProperty()->SetColor(1, 0, 0);
myRender->AddViewProp(cornerAnnotation);
this->Picker = propPicker;
//this->Annotation = cornerAnnotation;
// 利⽤ui界⾯的interactor 获取render的指针,⽤picker类获得⿏标的点
vtkRenderWindowInteractor *interactor = this->myViewer->GetRenderWindow()->GetInteractor(); vtkImageActor* actor = this->myViewer->GetImageActor();
vtkImageData *image2 = this->reader->GetOutput();
//if (pty())
//{
// cout << "Picture has not loading !" << endl;
// return -1;
//}
vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(interactor->GetInteractorStyle());
//Pick at the mouse location provided by the interactor
this->Picker->Pick(interactor->GetEventPosition()[0],
interactor->GetEventPosition()[1],0.0, this->myViewer->GetRenderer());
// There could be other props assigned to this picker, so
// make sure we picked the image actor
vtkAssemblyPath* path = this->Picker->GetPath();
bool validPick = false;
if (path)
{
vtkCollectionSimpleIterator sit;
path->InitTraversal(sit);
vtkAssemblyNode *node;
for (int i = 0; i < path->GetNumberOfItems() && !validPick; ++i)
{
node = path->GetNextNode(sit);
if (actor == vtkImageActor::SafeDownCast(node->GetViewProp()))
{
validPick = true;
}
}
}
if (!validPick)
{
//this->Annotation->SetText(0, "Off Image");
this->myViewer->GetRenderWindow()->GetInteractor()->Render();
// Pass the event further on
style->OnMouseMove();
return;
}
// Get the world coordinates of the pick

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论