We are using itkImageSeriesReader which support different
formats DICOM, JPEG, TIFF, PNG to read in a series but size of images should be
same. Then itkImageToVTKImageFilter will convert data from itk to vtk image
format that we will visualize through VTK+Qt pipeline. In VTK you can try both
viewers just by uncomment two lines of vtkImageViewer2 and comment lines of vtkResliceImageViewer.
Application have :
1. main.cpp
2. mainwindow.h
3. mainwindow.cpp
4. mainwindow.ui
5. CmakeLists.txt
Step 1. Copy XML code of ui form into a text editor and save
it as mainwindow.ui format. It will create ui.
Step 2. Create headers, cpp and cmake files.
Step 3. Cmake to generate project file, build and run.
Here is code
mainwindow.ui
<?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>419</width>
<height>350</height>
</rect>
</property>
<property
name="windowTitle">
<string>MainWindow</string>
</property>
<widget
class="QWidget" name="centralWidget">
<widget
class="QVTKWidget" name="qVTK1">
<property
name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>381</width>
<height>291</height>
</rect>
</property>
<property
name="sizePolicy">
<sizepolicy
hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</widget>
<widget
class="QMenuBar" name="menuBar">
<property
name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>419</width>
<height>21</height>
</rect>
</property>
<widget
class="QMenu" name="menu_File">
<property
name="title">
<string>&File</string>
</property>
<widget
class="QMenu" name="menu_Open">
<property
name="title">
<string>&Open</string>
</property>
<addaction
name="actionDICOM_Sequence"/>
</widget>
<addaction
name="menu_Open"/>
<addaction
name="separator"/>
<addaction
name="actionExit"/>
</widget>
<addaction
name="menu_File"/>
</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"/>
<action
name="actionJPEG">
<property
name="text">
<string>JPEG</string>
</property>
</action>
<action
name="actionDICOM">
<property
name="text">
<string>DICOM</string>
</property>
</action>
<action
name="actionDICOM_Sequence">
<property
name="text">
<string>DICOM
Sequence</string>
</property>
</action>
<action
name="actionExit">
<property
name="text">
<string>Exit</string>
</property>
</action>
</widget>
<layoutdefault
spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QVTKWidget</class>
<extends>QWidget</extends>
<header>QVTKWidget.h</header>
<container>1</container>
<slots>
<slot>sopenimage()</slot>
</slots>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
mainwindow.h
#ifndef
MAINWINDOW_H
#define
MAINWINDOW_H
#include <QMainWindow>
#include "vtkSmartPointer.h"
class
vtkImageViewer2;
class
vtkResliceImageViewer;
namespace Ui {
class
MainWindow;
}
class MainWindow
: public QMainWindow
{
Q_OBJECT
public:
explicit
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
int
DICOMseq();
private:
//vtkImageViewer2 *image_view;
vtkSmartPointer<vtkResliceImageViewer> image_view;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
//Qt
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QFileInfoList>
#include<QDir>
#include<iostream>
//ITK
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkImageToVTKImageFilter.h"
//VTK
#include "vtkImageViewer2.h"
#include "vtkResliceImageViewer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
using namespace std;
MainWindow::MainWindow(QWidget
*parent) :
QMainWindow(parent),
ui(new
Ui::MainWindow)
{
ui->setupUi(this);
//image_view =
vtkImageViewer2::New();
image_view =
vtkSmartPointer<vtkResliceImageViewer>::New();
//Qt Signal slot
connect(ui->actionDICOM_Sequence,SIGNAL(triggered()),this, SLOT(DICOMseq()));
connect(ui->actionExit,SIGNAL(triggered()),this, SLOT(close()));
}
MainWindow::~MainWindow()
{
delete ui;
}
int
MainWindow::DICOMseq()
{
typedef signed short InputPixelType;//Pixel Type
const unsigned
int InputDimension = 3;//Dimension
of image
typedef itk::Image<
InputPixelType, InputDimension > InputImageType;//Image
Type
typedef
itk::ImageSeriesReader< InputImageType > ReaderType;//Reader of Image Type
ReaderType::Pointer reader = ReaderType::New();
//Replacement of name generator of
ITK
QDir dir("Dir");
dir=QFileDialog::getExistingDirectory(0,"Select Folder: ");
QFileInfoList list = dir.entryInfoList(QDir::Dirs| QDir::Files
| QDir::NoDotAndDotDot);
std::vector<std::string> names;
foreach(QFileInfo finfo, list)
{
std::string
str=dir.path().toStdString().c_str();
str=str+"/";
names.push_back(str+finfo.fileName().toStdString().c_str());
}
reader->SetFileNames( names );
//Exceptional handling
try
{
reader->Update();
}
catch (itk::ExceptionObject
& e)
{
std::cerr << "exception
in file reader " << std::endl;
std::cerr << e << std::endl;
return EXIT_FAILURE;
}
/*
You can impliment your Filter here and
connect its output to connector below.
*/
//connector to convert ITK image data
to VTK image data
typedef
itk::ImageToVTKImageFilter<InputImageType> ConnectorType;
ConnectorType::Pointer connector= ConnectorType::New();
connector->SetInput( reader->GetOutput() );//Set ITK reader Output to connector you can replace it
with filter
//Exceptional handling
try
{
connector->Update();
}
catch (itk::ExceptionObject
& e)
{
std::cerr << "exception
in file reader " << std::endl;
std::cerr << e << std::endl;
return EXIT_FAILURE;
}
//deep copy connector's output to an
image else connector will go out of scope
//and vanish it will cause error
while changing slice
vtkImageData * image = vtkImageData::New();
image->DeepCopy(connector->GetOutput());
//set VTK Viewer to QVTKWidget in
Qt's UI
ui->qVTK1->SetRenderWindow(image_view->GetRenderWindow());
image_view->SetupInteractor(ui->qVTK1->GetRenderWindow()->GetInteractor());
//Set input image to VTK viewer
image_view->SetInput(image);
image_view->SetSlice(image_view->GetSliceMax()/2);
image_view->GetRenderer()->ResetCamera();
image_view->Render();
ui->qVTK1->update();
return EXIT_SUCCESS;
}
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char
*argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return
a.exec();
}
CmakeLists.txt
cmake_minimum_required(VERSION 2.6)
PROJECT(main)
IF(NOT VTK_BINARY_DIR)
FIND_PACKAGE(VTK)
IF(NOT VTK_DIR)
MESSAGE(FATAL_ERROR
"Please set VTK_DIR.")
ENDIF(NOT VTK_DIR)
INCLUDE(${VTK_USE_FILE})
ENDIF(NOT VTK_BINARY_DIR)
FIND_PACKAGE ( ITK)
IF ( ITK_FOUND)
INCLUDE( ${USE_ITK_FILE} )
ENDIF( ITK_FOUND)
SET(QT_QMAKE_EXECUTABLE ${VTK_QT_QMAKE_EXECUTABLE} CACHE
FILEPATH "")
SET(QT_MOC_EXECUTABLE ${VTK_QT_MOC_EXECUTABLE} CACHE FILEPATH
"")
SET(QT_UIC_EXECUTABLE ${VTK_QT_UIC_EXECUTABLE} CACHE FILEPATH
"")
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE(${QT_USE_FILE})
# Set your files and resources here
SET(Main main.cpp mainwindow.cpp)
SET(MainUI mainwindow.ui)
SET(MainH mainwindow.h)
INCLUDE_DIRECTORIES(
${QT_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
QT4_WRAP_UI(UISrcs ${MainUI})
QT4_WRAP_CPP(MOCSrcs ${MainH} )
SOURCE_GROUP("Resources" FILES
${MainUI}
)
SOURCE_GROUP("Generated" FILES
${UISrcs}
${MOCSrcs}
${RCS_SOURCES}
)
ADD_EXECUTABLE( main ${Main} ${UISrcs} ${MOCSrcs})
TARGET_LINK_LIBRARIES( main QVTK ${ITK_LIBRARIES} )
Nice post on VTK Itk and qt .
ReplyDeleteCan i comiple ITK-VTK application from Qt creater?
Yes you can by providing ITK VTK libraries' path in .pro file to use creator.
DeleteDo you have example of .pro file. if You have please send me the file how to add these itk vtk libraries in . pro file.
DeleteI create a simple vtk app add vtk libraries in .pro file it work . But when create a itk adding the header file it doesnot work. Please Help Me. I m new to itk vtk and Qt.
Thanks for your Help .
HTH http://itk-insight-users.2283740.n2.nabble.com/Including-ITK-in-QT-Creator-Project-ld-error-OSX-tt7409758.html#a7580667
DeleteThanks
ReplyDeleteHi That post is wonderful !
ReplyDeleteWas wondering if you heard about GDCMIOFactory registered error ? Because I cannot read dicom image.
Thank you for this post !
ReplyDeleteI got this error "‘class vtkResliceImageViewer’ has no member named ‘SetInput’"
I use ITK 4.5 with VTK 6.1
USE SetInputData
DeleteGreat ! it works without changing 'setInput', but the image view is upside (tested for DICOM)
DeleteI use ITK 4.5 VTK 6.1 QT 5.2.1
Hi have you changed in the CmakeLists.txt for Qt version?
DeleteThis comment has been removed by the author.
ReplyDeleteNice post.
ReplyDeleteGreat Help.
CmakeLists.txt
it is INCLUDE(${ITK_USE_FILE}) not INCLUDE(${USE_ITK_FILE})
I use QT 4.8, it can't be use.
ReplyDeletewhat QT version should I used for?
Great and I have a swell give: How Much Full House Renovation Cost renovations to increase home value
ReplyDelete