├── About.cpp ├── About.h ├── About.qrc ├── About.ui ├── CMakeLists.txt ├── CTK ├── CTK.rar └── README ├── Crosshair.cpp ├── Crosshair.h ├── Crosshair.qrc ├── Crosshair.ui ├── DistanceMeasurement.cpp ├── DistanceMeasurement.h ├── DistanceMeasurement.qrc ├── DistanceMeasurement.ui ├── ImageToSTL.cpp ├── ImageToSTL.h ├── ImageToSTL.qrc ├── ImageToSTL.ui ├── Medical Image Data ├── ReadMe ├── heart.mhd ├── heart.raw ├── nucleon.mhd └── nucleon.raw ├── MedicalImageTool.cpp ├── MedicalImageTool.h ├── MedicalImageTool.qrc ├── MedicalImageTool.ui ├── README.md ├── Resources ├── 1.png ├── 2.png ├── 3.jpg ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.jpg ├── 9.png ├── README ├── exit.png ├── fileopen.png ├── filesave.png └── splashscreen.PNG ├── Result ├── README ├── pic1.png ├── pic2.png └── pic3.png ├── STLSet.cpp ├── STLSet.h ├── STLSet.qrc ├── STLSet.ui ├── Slicer ├── README └── Slicer.rar ├── VolumeRenderer.cpp ├── VolumeRenderer.h ├── VolumeRenderer.qrc ├── VolumeRenderer.ui └── main.cpp /About.cpp: -------------------------------------------------------------------------------- 1 | #include "About.h" 2 | 3 | About::About(QWidget *parent, Qt::WFlags flags) 4 | : QDialog(parent, flags), ui(new Ui::About) 5 | { 6 | ui->setupUi(this); 7 | this->setWindowTitle("About Medical Image Tool"); 8 | this->setMaximumSize(529, 391); 9 | this->setMinimumSize(529, 391); 10 | } 11 | 12 | About::~About() 13 | { 14 | delete ui; 15 | } 16 | 17 | void About::on_pushButton_clicked() 18 | { 19 | this->close(); 20 | } -------------------------------------------------------------------------------- /About.h: -------------------------------------------------------------------------------- 1 | #ifndef ABOUT_H 2 | #define ABOUT_H 3 | 4 | #include 5 | #include "ui_About.h" 6 | 7 | namespace Ui 8 | { 9 | class About; 10 | } 11 | 12 | class About : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | About(QWidget *parent = 0, Qt::WFlags flags = 0); 18 | ~About(); 19 | 20 | private: 21 | Ui::About *ui; 22 | 23 | private slots: 24 | void on_pushButton_clicked(); 25 | }; 26 | 27 | #endif // ABOUT_H 28 | -------------------------------------------------------------------------------- /About.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/3.jpg 4 | Resources/4.png 5 | 6 | 7 | -------------------------------------------------------------------------------- /About.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | About 4 | 5 | 6 | 7 | 0 8 | 0 9 | 529 10 | 391 11 | 12 | 13 | 14 | About 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 0 23 | 0 24 | 531 25 | 391 26 | 27 | 28 | 29 | background-image: url(:/About/Resources/3.jpg); 30 | 31 | 32 | <html><head/><body><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">Program:Medical Image Tool</span><span style=" color:#ff007f;"><br/></span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">Language:C++</span><span style=" color:#ff007f;"><br/></span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">Version:1.0</span><span style=" color:#ff007f;"><br/></span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">Author:WangJianjun(QQ:2426350401)</span></p><p><span style=" color:#ff007f;"><br/></span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">Copyright (c) College of Biomedical Engineering,</span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">South-Central University for Nationalities. </span></p><p><span style=" font-size:12pt; font-weight:600; color:#ff007f;">All rights reserved.</span></p></body></html> 33 | 34 | 35 | 36 | 37 | 38 | 450 39 | 360 40 | 71 41 | 23 42 | 43 | 44 | 45 | background-image: url(:/About/Resources/4.png); 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | 3 | project(MedicalImageTool) 4 | 5 | # Find the Qt VTK ITK directory 6 | set(ITK_DIR "D:/InstallApplication/ITK/ITK_bin" CACHE PATH "ITK directory") 7 | set(VTK_DIR "D:/InstallApplication/VTK/VTK_bin" CACHE PATH "VTK directory") 8 | 9 | find_package( ITK ) 10 | find_package( VTK REQUIRED ) 11 | # find_package( Qt4 REQUIRED ) 12 | 13 | FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtOpenGL QtNetwork REQUIRED) 14 | 15 | include( ${ITK_USE_FILE} ) 16 | include( ${VTK_USE_FILE} ) 17 | include( ${QT_USE_FILE} ) 18 | 19 | # Set Qt file directory of source code 20 | set(Qt_HDR_files 21 | About.h 22 | Crosshair.h 23 | DistanceMeasurement.h 24 | VolumeRenderer.h 25 | ImageToSTL.h 26 | STLSet.h 27 | MedicalImageTool.h) 28 | 29 | set(Qt_SRC_files 30 | main.cpp 31 | About.cpp 32 | Crosshair.cpp 33 | DistanceMeasurement.cpp 34 | VolumeRenderer.cpp 35 | ImageToSTL.cpp 36 | STLSet.cpp 37 | MedicalImageTool.cpp) 38 | 39 | set(Qt_RES_files 40 | About.qrc 41 | Crosshair.qrc 42 | DistanceMeasurement.qrc 43 | VolumeRenderer.qrc 44 | ImageToSTL.qrc 45 | STLSet.qrc 46 | MedicalImageTool.qrc) 47 | 48 | set(Qt_UI_files 49 | About.ui 50 | Crosshair.ui 51 | DistanceMeasurement.ui 52 | VolumeRenderer.ui 53 | ImageToSTL.ui 54 | STLSet.ui 55 | MedicalImageTool.ui) 56 | 57 | qt4_wrap_ui(MOC_UI ${Qt_UI_files}) 58 | qt4_wrap_cpp(MOC_SRC ${Qt_HDR_files}) 59 | qt4_add_resources(MOC_RES ${Qt_RES_files}) 60 | 61 | source_group("Form Files" FILES ${Qt_UI_files}) 62 | source_group("Generated Files" FILES ${MOC_UI} ${MOC_SRC}) 63 | source_group("Resources Files" FILES ${Qt_RES_files} ${MOC_RES}) 64 | 65 | # CTK------------------------------------------------------------------------------------------------------------ 66 | # CTK paths 67 | set(CTK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/CTK" CACHE PATH "CTK directory") 68 | set(CTK_Libs_Core_DIR "${CTK_DIR}/Libs/Core") 69 | set(CTK_Libs_Widgets_DIR "${CTK_DIR}/Libs/Widgets") 70 | set(CTK_Libs_Visualization_VTK_Core_DIR "${CTK_DIR}/Libs/Visualization/VTK/Core") 71 | set(CTK_Libs_Visualization_VTK_Widgets_DIR "${CTK_DIR}/Libs/Visualization/VTK/Widgets") 72 | file(GLOB CTK_header_files 73 | ${CTK_Libs_Core_DIR}/*.h 74 | ${CTK_Libs_Widgets_DIR}/*.h 75 | ${CTK_Libs_Visualization_VTK_Core_DIR}/*.h 76 | ${CTK_Libs_Visualization_VTK_Widgets_DIR}/*.h) 77 | 78 | file(GLOB CTK_source_files 79 | ${CTK_Libs_Core_DIR}/*.h 80 | ${CTK_Libs_Core_DIR}/*.cpp 81 | ${CTK_Libs_Widgets_DIR}/*.h 82 | ${CTK_Libs_Widgets_DIR}/*.cpp 83 | ${CTK_Libs_Visualization_VTK_Core_DIR}/*.h 84 | ${CTK_Libs_Visualization_VTK_Core_DIR}/*.cpp 85 | ${CTK_Libs_Visualization_VTK_Widgets_DIR}/*.h 86 | ${CTK_Libs_Visualization_VTK_Widgets_DIR}/*.cpp) 87 | 88 | file(GLOB CTK_qrc_files 89 | ${CTK_Libs_Widgets_DIR}/Resources/*.qrc 90 | ${CTK_Libs_Visualization_VTK_Widgets_DIR}/Resources/*.qrc) 91 | 92 | file(GLOB CTK_ui_files 93 | ${CTK_Libs_Widgets_DIR}/Resources/UI/*.ui 94 | ${CTK_Libs_Visualization_VTK_Widgets_DIR}/Resources/UI/*.ui) 95 | 96 | # CTK 97 | source_group(CTK FILES ${CTK_header_files} ${CTK_source_files}) 98 | message(STATUS "CTK header files: " ${CTK_header_files}) 99 | message(STATUS "CTK source files: " ${CTK_source_files}) 100 | QT4_WRAP_CPP(CTK_moc_source_files ${CTK_header_files}) 101 | message(STATUS "CTK moc source files: " ${CTK_moc_source_files}) 102 | source_group(CTK_moc FILES ${CTK_moc_source_files}) 103 | QT4_WRAP_UI(CTK_ui_header_files ${CTK_ui_files}) 104 | message(STATUS "CTK ui header files: " ${CTK_ui_header_files}) 105 | QT4_ADD_RESOURCES(CTK_qrc_complied ${CTK_qrc_files}) 106 | source_group(CTK_ui FILES ${CTK_ui_header_files} ${CTK_ui_files} ${CTK_qrc_files} ${CTK_qrc_complied}) 107 | 108 | # Slicer 109 | set(Slicer_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Slicer/Modules/Loadable/VolumeRendering/VolumeRenderingReplacements) 110 | file(GLOB Slicer_files 111 | ${Slicer_DIR}/*.h 112 | ${Slicer_DIR}/*.cxx) 113 | 114 | source_group(Slicer FILES ${Slicer_files}) 115 | 116 | # Set ITK file directory of source code 117 | set(ITK_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ITK" CACHE PATH "ITK SRC directory") 118 | file(GLOB ITK_files 119 | ${ITK_SRC_DIR}/*.h 120 | ${ITK_SRC_DIR}/*.hxx) 121 | 122 | # Set VTK file directory of source code 123 | set(VTK_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/VTK" CACHE PATH "ITK SRC directory") 124 | file(GLOB VTK_files 125 | ${VTK_SRC_DIR}/*.h 126 | ${VTK_SRC_DIR}/*.cpp 127 | ${VTK_SRC_DIR}/*.cxx) 128 | 129 | 130 | # Add the include directories for VTK and Qt 4 Widgets module to the compile lines. 131 | include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} 132 | ${PROJECT_SOURCE_DIR} 133 | ${VTK_DIR} ${ITK_DIR} 134 | ${ITK_SRC_DIR} ${VTK_SRC_DIR} 135 | ${CTK_Libs_Core_DIR} ${CTK_Libs_Widgets_DIR} ${CTK_Libs_Visualization_VTK_Core_DIR} ${CTK_Libs_Visualization_VTK_Widgets_DIR} 136 | ${Slicer_DIR}) 137 | 138 | add_executable(${PROJECT_NAME} 139 | ${Qt_HDR_files} ${Qt_SRC_files} ${Qt_UI_files} ${Qt_QRC_files} 140 | ${MOC_UI} ${MOC_SRC} ${MOC_RES} 141 | ${ITK_files} ${VTK_files} 142 | ${CTK_header_files} ${CTK_source_files} ${CTK_moc_source_files} ${CTK_ui_header_files} ${CTK_qrc_complied} 143 | ${Slicer_files}) 144 | 145 | target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES} ${ITK_LIBRARIES}) 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /CTK/CTK.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/CTK/CTK.rar -------------------------------------------------------------------------------- /CTK/README: -------------------------------------------------------------------------------- 1 | Volume renderer of CTK 2 | -------------------------------------------------------------------------------- /Crosshair.cpp: -------------------------------------------------------------------------------- 1 | #include "Crosshair.h" 2 | 3 | Crosshair::Crosshair(QWidget *parent, Qt::WFlags flags) 4 | : QWidget(parent, flags), ui(new Ui::Crosshair) 5 | { 6 | ui->setupUi(this); 7 | 8 | this->setWindowTitle("Crosshair"); 9 | 10 | this->setMaximumSize(371, 291); 11 | this->setMinimumSize(371, 291); 12 | } 13 | 14 | Crosshair::~Crosshair() 15 | { 16 | delete ui; 17 | } 18 | 19 | void Crosshair::on_pushButtonClose_clicked() 20 | { 21 | this->close(); 22 | } -------------------------------------------------------------------------------- /Crosshair.h: -------------------------------------------------------------------------------- 1 | #ifndef CROSSHAIR_H 2 | #define CROSSHAIR_H 3 | 4 | #include 5 | #include "ui_Crosshair.h" 6 | 7 | namespace Ui 8 | { 9 | class Crosshair; 10 | } 11 | 12 | class Crosshair : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | Crosshair(QWidget *parent = 0, Qt::WFlags flags = 0); 18 | ~Crosshair(); 19 | 20 | Ui::Crosshair *ui; 21 | 22 | private: 23 | // Ui::Crosshair *ui; 24 | 25 | private slots: 26 | void on_pushButtonClose_clicked(); 27 | }; 28 | 29 | #endif // CROSSHAIR_H 30 | -------------------------------------------------------------------------------- /Crosshair.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/2.png 4 | Resources/6.png 5 | Resources/7.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /Crosshair.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Crosshair 4 | 5 | 6 | 7 | 0 8 | 0 9 | 375 10 | 293 11 | 12 | 13 | 14 | Crosshair 15 | 16 | 17 | 18 | 19 | 40 20 | 20 21 | 151 22 | 17 23 | 24 | 25 | 26 | Oblique Reslice 27 | 28 | 29 | 30 | 31 | 32 | 40 33 | 50 34 | 111 35 | 17 36 | 37 | 38 | 39 | Thick Slab 40 | 41 | 42 | 43 | 44 | 45 | 40 46 | 90 47 | 201 48 | 91 49 | 50 | 51 | 52 | Blend mode 53 | 54 | 55 | 56 | 57 | 10 58 | 20 59 | 181 60 | 17 61 | 62 | 63 | 64 | Min Intensity Blend 65 | 66 | 67 | 68 | 69 | 70 | 10 71 | 40 72 | 181 73 | 17 74 | 75 | 76 | 77 | Max Intensity Blend 78 | 79 | 80 | 81 | 82 | 83 | 10 84 | 60 85 | 111 86 | 17 87 | 88 | 89 | 90 | Mean Blend 91 | 92 | 93 | 94 | 95 | 96 | 97 | 310 98 | 230 99 | 50 100 | 50 101 | 102 | 103 | 104 | border-image: url(:/Crosshair/Resources/6.png); 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 40 114 | 200 115 | 65 116 | 65 117 | 118 | 119 | 120 | border-image: url(:/Crosshair/Resources/7.png); 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 0 130 | 0 131 | 371 132 | 291 133 | 134 | 135 | 136 | background-image: url(:/Crosshair/Resources/2.png); 137 | 138 | 139 | 140 | 141 | 142 | 143 | label 144 | resliceModeCheckBox 145 | thickModeCheckBox 146 | blendModeGroupBox 147 | pushButtonClose 148 | resetButton 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /DistanceMeasurement.cpp: -------------------------------------------------------------------------------- 1 | #include "DistanceMeasurement.h" 2 | 3 | DistanceMeasurement::DistanceMeasurement(QWidget *parent, Qt::WFlags flags) 4 | : QWidget(parent, flags),ui(new Ui::DistanceMeasurement) 5 | { 6 | ui->setupUi(this); 7 | this->setWindowTitle("DistanceMeasurement"); 8 | this->setMaximumSize(311, 241); 9 | this->setMinimumSize(311, 241); 10 | } 11 | 12 | DistanceMeasurement::~DistanceMeasurement() 13 | { 14 | delete ui; 15 | } 16 | -------------------------------------------------------------------------------- /DistanceMeasurement.h: -------------------------------------------------------------------------------- 1 | #ifndef DISTANCEMEASUREMENT_H 2 | #define DISTANCEMEASUREMENT_H 3 | 4 | #include 5 | #include "ui_DistanceMeasurement.h" 6 | 7 | namespace Ui 8 | { 9 | class DistanceMeasurement; 10 | } 11 | 12 | class DistanceMeasurement : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | DistanceMeasurement(QWidget *parent = 0, Qt::WFlags flags = 0); 18 | ~DistanceMeasurement(); 19 | 20 | Ui::DistanceMeasurement *ui; 21 | private: 22 | // Ui::DistanceMeasurement *ui; 23 | }; 24 | 25 | #endif // DISTANCEMEASUREMENT_H 26 | -------------------------------------------------------------------------------- /DistanceMeasurement.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/8.jpg 4 | 5 | 6 | -------------------------------------------------------------------------------- /DistanceMeasurement.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DistanceMeasurement 4 | 5 | 6 | 7 | 0 8 | 0 9 | 313 10 | 230 11 | 12 | 13 | 14 | DistanceMeasurement 15 | 16 | 17 | 18 | 19 | 0 20 | 0 21 | 311 22 | 231 23 | 24 | 25 | 26 | image: url(:/DistanceMeasurement/Resources/8.jpg); 27 | 28 | 29 | QFrame::StyledPanel 30 | 31 | 32 | QFrame::Raised 33 | 34 | 35 | 36 | 37 | 10 38 | 20 39 | 271 40 | 23 41 | 42 | 43 | 44 | Distance Measure on Axial Plane 45 | 46 | 47 | 48 | 49 | 50 | 10 51 | 70 52 | 271 53 | 23 54 | 55 | 56 | 57 | Distance Measure on Sagital Plane 58 | 59 | 60 | 61 | 62 | 63 | 10 64 | 130 65 | 271 66 | 23 67 | 68 | 69 | 70 | Distance Measure on Coronal Plane 71 | 72 | 73 | 74 | 75 | 76 | 10 77 | 190 78 | 271 79 | 23 80 | 81 | 82 | 83 | Distance Measure on 3D View 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /ImageToSTL.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageToSTL.h" 2 | 3 | // Itk class 4 | #include "itkStatisticsImageFilter.h" 5 | 6 | // Vtk header file 7 | #include "vtkImageFlip.h" 8 | #include "vtkImageCast.h" 9 | #include "vtkImageMapper3D.h" 10 | 11 | // Vtk connect qt 12 | #include 13 | 14 | // Vtk actor property 15 | #include "vtkImageProperty.h" 16 | 17 | // Vtk tracer 18 | #include "vtkImageTracerWidget.h" 19 | // Vtk tracer property 20 | #include "vtkProperty.h" 21 | 22 | // Vtk call back 23 | #include "vtkCallbackCommand.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | 37 | // Qt header file 38 | #include 39 | #include 40 | #include 41 | 42 | void CallbackFunction(vtkObject* caller, 43 | long unsigned int vtkNotUsed(eventId), 44 | void* vtkNotUsed(clientData), 45 | void* vtkNotUsed(callData)); 46 | 47 | ImageToSTL::ImageToSTL(QWidget *parent, Qt::WFlags flags) 48 | : QMainWindow(parent, flags), ui(new Ui::ImageToSTL) 49 | { 50 | ui->setupUi(this); 51 | this->setWindowTitle("Image To STL"); 52 | 53 | 54 | ui->groupBox->setMaximumSize(201, 221); 55 | ui->groupBox->setMinimumSize(201, 221); 56 | 57 | this->ui->labelXCoordinate->setAlignment(Qt::AlignCenter); 58 | this->ui->labelYCoordinate->setAlignment(Qt::AlignCenter); 59 | this->ui->labelZCoordinate->setAlignment(Qt::AlignCenter); 60 | 61 | this->ui->labelImageName->setAlignment(Qt::AlignCenter); 62 | this->ui->labelImageIntensity->setAlignment(Qt::AlignCenter); 63 | 64 | ui->labelSourceImageSliceNum->setMaximumSize(30, 20); 65 | ui->labelSourceImageSliceNum->setMinimumSize(30, 20); 66 | ui->labelSourceImageSliceNum->setAlignment(Qt::AlignCenter); 67 | 68 | ui->divideLineLabel1->setMaximumSize(30, 20); 69 | ui->divideLineLabel1->setMinimumSize(30, 20); 70 | ui->divideLineLabel1->setAlignment(Qt::AlignCenter); 71 | 72 | ui->labelSourceImageSliceTotal->setMaximumSize(30, 20); 73 | ui->labelSourceImageSliceTotal->setMinimumSize(30, 20); 74 | ui->labelSourceImageSliceTotal->setAlignment(Qt::AlignCenter); 75 | 76 | //initialize the inputSourceImageReader and inputSourceImage variable 77 | itkImageReader = ITKReadType::New(); 78 | itkInputSourceImage = ITKImageType::New(); 79 | itkToVtkConnector = ITKtoVTKConnectorType::New(); 80 | 81 | // initialize vtk variable 82 | imageData = vtkSmartPointer::New(); 83 | vtkWindowLevel = vtkSmartPointer::New(); 84 | imageActor = vtkSmartPointer::New(); 85 | vtkRender = vtkSmartPointer::New(); 86 | renderWindow = vtkSmartPointer::New(); 87 | renderWinInteractor = vtkSmartPointer::New(); 88 | interactorStyleImage = vtkSmartPointer::New(); 89 | interactorStyleGetPixel = vtkSmartPointer::New(); 90 | 91 | this->currentInteractorStyle = interactorStyleGetPixel; 92 | 93 | // make vtk render window to display qvtkWidget 94 | ui->qvtkWidgetDisplaySourceImage->SetRenderWindow(renderWindow); 95 | 96 | // Vtk connect Qt slots 97 | vtkConnectQt = vtkEventQtSlotConnect::New(); 98 | vtkConnectQt->Connect(renderWinInteractor, vtkCommand::MouseMoveEvent, this, SLOT(updateCoordinate(vtkObject*))); 99 | 100 | stlParameterSet = new STLSet; 101 | polyData = vtkSmartPointer::New(); 102 | 103 | this->initialWindow = 1000; 104 | this->initialLevel = 0; 105 | } 106 | 107 | ImageToSTL::~ImageToSTL() 108 | { 109 | delete ui; 110 | delete stlParameterSet; 111 | } 112 | 113 | // Prompt message whether to input source image 114 | void ImageToSTL::inputSourceImagePromptMessage() 115 | { 116 | if (inputSourceImageAllName.isEmpty()) 117 | { 118 | QMessageBox::information(this, "Prompt Message", "Please input source Image !"); 119 | return; 120 | } 121 | } 122 | 123 | // Adjust input source image's window and level 124 | void ImageToSTL::setSourceImageLevel() 125 | { 126 | inputSourceImagePromptMessage(); 127 | this->inputSourceImageLevel = ui->lineEditSourceImageLevel->text().toFloat(); 128 | this->vtkWindowLevel->SetLevel(this->inputSourceImageLevel); 129 | vtkRender->ResetCamera(); 130 | renderWindow->Render(); 131 | } 132 | 133 | void ImageToSTL::setSourceImageWindow() 134 | { 135 | inputSourceImagePromptMessage(); 136 | this->inputSourceImageWindow = ui->lineEditSourceImageWindow->text().toFloat(); 137 | this->vtkWindowLevel->SetWindow(this->inputSourceImageWindow); 138 | vtkRender->ResetCamera(); 139 | renderWindow->Render(); 140 | } 141 | 142 | void ImageToSTL::setSourceImageSliceSlot(int slice) 143 | { 144 | inputSourceImagePromptMessage(); 145 | 146 | // Change input image slice to show 147 | ui->sliceSourceImagePosition->setRange(0, itkInputSourceImageSize[2] - 1); 148 | ui->labelSourceImageSliceNum->setText(QString::number(slice)); 149 | 150 | // imageActor->SetDisplayExtent(0, itkInputSourceImageSize[0] - 1, 0, itkInputSourceImageSize[1] - 1, slice, slice); 151 | 152 | // If you use the Scribble and GetPixel interactor style, you must be update the style input information 153 | interactorStyleGetPixel->SetInputInfo(imageData, imageActor, slice); 154 | 155 | // if using the ResetCameraClippingRange function, the image display size will be as the number changes in size 156 | // vtkRender->ResetCameraClippingRange(); 157 | vtkRender->ResetCamera(); 158 | renderWindow->Render(); 159 | } 160 | 161 | void ImageToSTL::openSourceImageSlot() 162 | { 163 | inputSourceImageAllName = QFileDialog::getOpenFileName(this, "Open Image", 164 | "../Image", tr("Image Files(*.png *.jpg *.bmp *.jpeg *.dcm *.mhd *.mha *.nii *.hdr)")); 165 | inputSourceImagePromptMessage(); 166 | 167 | // Get the input image name 168 | QFileInfo inputImageNameInfo = QFileInfo(inputSourceImageAllName); 169 | // inputSourceImageName = inputImageNameInfo.fileName(); 170 | inputSourceImageName = inputImageNameInfo.baseName(); 171 | ui->labelImageName->setText(inputSourceImageName); 172 | 173 | // Read the source image 174 | itkImageReader->SetFileName(inputSourceImageAllName.toStdString()); 175 | itkImageReader->Update(); 176 | itkInputSourceImage = itkImageReader->GetOutput(); 177 | itkInputSourceImageSize = itkInputSourceImage->GetLargestPossibleRegion().GetSize(); 178 | 179 | ui->labelSourceImageSliceTotal->setText(QString::number(itkInputSourceImageSize[2] - 1)); 180 | // initialize the source image's first slice 181 | ui->labelSourceImageSliceNum->setText(QString::number(0)); 182 | 183 | // itk image data to vtk image data 184 | itkToVtkConnector->SetInput(itkInputSourceImage); 185 | itkToVtkConnector->Update(); 186 | 187 | // flip image 188 | vtkSmartPointer vtkFlipImageFilter = vtkSmartPointer::New(); 189 | vtkFlipImageFilter->SetInputData(itkToVtkConnector->GetOutput()); 190 | vtkFlipImageFilter->SetFilteredAxes(1); 191 | vtkFlipImageFilter->Update(); 192 | 193 | // cast float type image to int, that make display image better 194 | vtkSmartPointer vtkImageCastFilter = vtkSmartPointer::New(); 195 | vtkImageCastFilter->SetInputData(vtkFlipImageFilter->GetOutput()); 196 | vtkImageCastFilter->SetOutputScalarTypeToInt(); 197 | vtkImageCastFilter->Update(); 198 | 199 | this->imageData = vtkImageCastFilter->GetOutput(); 200 | 201 | vtkWindowLevel->SetInputConnection(vtkImageCastFilter->GetOutputPort()); 202 | // The Window and Level is empirical value 203 | this->calculateSuitableWinLev(); 204 | 205 | vtkWindowLevel->SetWindow(this->initialWindow); 206 | vtkWindowLevel->SetLevel(this->initialLevel); 207 | 208 | // Display image window and level 209 | ui->lineEditSourceImageLevel->setValue(this->vtkWindowLevel->GetLevel()); 210 | ui->lineEditSourceImageWindow->setValue(this->vtkWindowLevel->GetWindow()); 211 | 212 | imageActor->GetMapper()->SetInputConnection(vtkWindowLevel->GetOutputPort()); 213 | vtkRender->AddActor(imageActor); 214 | renderWindow->AddRenderer(vtkRender); 215 | renderWindow->Render(); 216 | 217 | renderWinInteractor->SetInteractorStyle(interactorStyleGetPixel); 218 | renderWinInteractor->SetRenderWindow(renderWindow); 219 | renderWinInteractor->Initialize(); 220 | 221 | interactorStyleGetPixel->SetInputInfo(imageData, imageActor, 0); 222 | // interactorStyleScribble->SetCurrentRenderer(vtkRender); 223 | // interactorStyleGetPixel->AddObserver(this->interactorStyleGetPixel->ScribbleEvent, this, &GraphCutsUI::ScribbleEventHandler); 224 | // interactorStyleScribble->SetColorToRed(); 225 | // // this must come after the SetInteractorStyle call 226 | // interactorStyleScribble->InitializeTracer(); 227 | 228 | // vtkSmartPointer tracer = vtkSmartPointer::New(); 229 | // tracer->GetLineProperty()->SetLineWidth(5); 230 | // tracer->GetLineProperty()->SetOpacity(1); 231 | // tracer->SetInteractor(renderWinInteractor); 232 | // tracer->SetViewProp(imageActor); 233 | // tracer->ProjectToPlaneOn(); 234 | 235 | // The observer must be added BEFORE the On() call. 236 | // vtkSmartPointer callback = 237 | // vtkSmartPointer::New(); 238 | // callback->SetCallback(CallbackFunction); 239 | // tracer->AddObserver(vtkCommand::EndInteractionEvent, callback); 240 | // tracer->On(); 241 | 242 | // Set image actor opacity 243 | // imageActor->GetProperty()->SetOpacity(0); 244 | 245 | vtkRender->ResetCamera(); 246 | renderWinInteractor->Start(); 247 | } 248 | 249 | // Display current pixel's coordinate and value 250 | void ImageToSTL::displayPixelCoordinateAndValue() 251 | { 252 | // Display coordinate 253 | ui->labelXCoordinate->setText(QString::number(this->interactorStyleGetPixel->GetCurrentPixelCoordinate()[0])); 254 | ui->labelYCoordinate->setText(QString::number(this->interactorStyleGetPixel->GetCurrentPixelCoordinate()[1])); 255 | ui->labelZCoordinate->setText(QString::number(this->interactorStyleGetPixel->GetCurrentPixelCoordinate()[2])); 256 | 257 | // Display pixel value 258 | ui->labelImageIntensity->setText(QString::number(this->interactorStyleGetPixel->GetCurrentPixelValue())); 259 | } 260 | 261 | 262 | // Update current coordinate 263 | void ImageToSTL::updateCoordinate(vtkObject* obj) 264 | { 265 | this->displayPixelCoordinateAndValue(); 266 | } 267 | 268 | void CallbackFunction(vtkObject* caller, 269 | long unsigned int vtkNotUsed(eventId), 270 | void* vtkNotUsed(clientData), 271 | void* vtkNotUsed(callData)) 272 | { 273 | // vtkImageTracerWidget* tracerWidget = 274 | // static_cast(caller); 275 | // vtkSmartPointer path = 276 | // vtkSmartPointer::New(); 277 | // tracerWidget->GetPath(path); 278 | // std::cout << "There are " << path->GetNumberOfPoints() << " points in the path." << std::endl; 279 | } 280 | 281 | // Screenshot 282 | void ImageToSTL::ViewPaneScreenshot(QVTKWidget *widget) 283 | { 284 | QString fileName = QFileDialog::getSaveFileName(this, "Save Screenshot", "", "Pircture Files (*.png *.jpg)"); 285 | if (fileName.isEmpty()) 286 | { 287 | return; 288 | } 289 | 290 | vtkSmartPointer windowToImageFilter = 291 | vtkSmartPointer::New(); 292 | windowToImageFilter->SetInput(widget->GetRenderWindow()); 293 | //windowToImageFilter->SetMagnification(3); 294 | windowToImageFilter->Update(); 295 | 296 | vtkSmartPointer writer = 297 | vtkSmartPointer::New(); 298 | writer->SetFileName(fileName.toStdString().c_str()); 299 | writer->SetInputConnection(windowToImageFilter->GetOutputPort()); 300 | writer->Write(); 301 | } 302 | 303 | void ImageToSTL::on_actionScreenshotLeft_triggered() 304 | { 305 | ViewPaneScreenshot(this->ui->qvtkWidgetDisplaySourceImage); 306 | } 307 | 308 | void ImageToSTL::on_actionScreenshotRight_triggered() 309 | { 310 | ViewPaneScreenshot(this->ui->qvtkWidgetPolyData); 311 | } 312 | 313 | // View 314 | void ImageToSTL::on_actionDisplayPly_triggered() 315 | { 316 | vtkImageDataToPly(); 317 | 318 | //vtkSmartPointer imgViewer = vtkSmartPointer::New(); 319 | 320 | vtkSmartPointer cylinderMapper = 321 | vtkSmartPointer::New(); 322 | cylinderMapper->SetInputData( polyData ); 323 | 324 | vtkSmartPointer cylinderActor = 325 | vtkSmartPointer::New(); 326 | cylinderActor->SetMapper( cylinderMapper ); 327 | cylinderActor->GetProperty()->SetColor(1.0, 0.0, 0.0); 328 | 329 | vtkSmartPointer renderer = 330 | vtkSmartPointer::New(); 331 | renderer->AddActor( cylinderActor ); 332 | renderer->SetBackground( 1.0, 1.0, 1.0 ); 333 | 334 | vtkSmartPointer renWin = 335 | vtkSmartPointer::New(); 336 | renWin->AddRenderer( renderer ); 337 | renWin->SetSize( 640, 480 ); 338 | renWin->Render(); 339 | renWin->SetWindowName("RenderCylinder"); 340 | 341 | this->ui->qvtkWidgetPolyData->SetRenderWindow(renWin); 342 | 343 | vtkSmartPointer iren = 344 | vtkSmartPointer::New(); 345 | iren->SetRenderWindow(renWin); 346 | 347 | vtkSmartPointer style = 348 | vtkSmartPointer::New(); 349 | iren->SetInteractorStyle(style); 350 | 351 | //display axis 352 | vtkSmartPointer axesActor = vtkSmartPointer::New(); 353 | vtkSmartPointer axesWidget = vtkSmartPointer::New(); 354 | axesWidget->SetOrientationMarker(axesActor); 355 | axesWidget->SetInteractor(iren); 356 | axesWidget->On(); 357 | axesWidget->SetInteractive(0); 358 | 359 | iren->Initialize(); 360 | iren->Start(); 361 | 362 | } 363 | 364 | void ImageToSTL::vtkImageDataToPly() 365 | { 366 | if (!this->stlParameterSet->ui->lineEditIosValue->text().isEmpty()) 367 | { 368 | isoValue = this->stlParameterSet->ui->lineEditIosValue->text().toFloat(); 369 | } 370 | this->imageData->DeepCopy(itkToVtkConnector->GetOutput()); 371 | 372 | vtkSmartPointer surface = 373 | vtkSmartPointer::New(); 374 | surface->SetInputData(imageData); 375 | 376 | surface->ComputeNormalsOn(); 377 | surface->SetValue(0, isoValue); 378 | surface->Update(); 379 | polyData = surface->GetOutput(); 380 | } 381 | 382 | void ImageToSTL::on_actionSavePly_triggered() 383 | { 384 | vtkImageDataToPly(); 385 | QString fileName = QFileDialog::getSaveFileName(this, "Save Ply", "", "Ply Files(*.ply)"); 386 | if (fileName.isEmpty()) 387 | { 388 | QMessageBox::information(this, "Prompt Message", "Please input the name of save ply file!"); 389 | return; 390 | } 391 | vtkSmartPointer plyWriter = vtkSmartPointer::New(); 392 | plyWriter->SetFileName(fileName.toStdString().c_str()); 393 | plyWriter->SetFileTypeToASCII(); 394 | plyWriter->SetInputData(polyData); 395 | plyWriter->Write(); 396 | } 397 | 398 | void ImageToSTL::on_actionSaveSTL_triggered() 399 | { 400 | vtkImageDataToPly(); 401 | QString fileName = QFileDialog::getSaveFileName(this, "Save STL", "", "Ply Files(*.stl)"); 402 | if (fileName.isEmpty()) 403 | { 404 | QMessageBox::information(this, "Prompt Message", "Please input the name of save ply file!"); 405 | return; 406 | } 407 | 408 | vtkSmartPointer stlFilter = vtkSmartPointer::New(); 409 | stlFilter->SetInputData(polyData); 410 | vtkSmartPointer stlWriter = 411 | vtkSmartPointer::New(); 412 | stlWriter->SetFileName(fileName.toStdString().c_str()); 413 | stlWriter->SetInputConnection(stlFilter->GetOutputPort()); 414 | stlWriter->Write(); 415 | } 416 | 417 | // Parameter set 418 | void ImageToSTL::on_actionSTLSet_triggered() 419 | { 420 | this->stlParameterSet->show(); 421 | } 422 | 423 | void ImageToSTL::calculateSuitableWinLev() 424 | { 425 | typedef itk::StatisticsImageFilter< ITKImageType > StatisticsFilterType; 426 | StatisticsFilterType::Pointer statisticsFilter = StatisticsFilterType::New(); 427 | statisticsFilter->SetInput(this->itkInputSourceImage); 428 | statisticsFilter->Update(); 429 | 430 | this->initialWindow = statisticsFilter->GetMaximum() - statisticsFilter->GetMinimum(); 431 | this->initialLevel = this->initialWindow / 2; 432 | } -------------------------------------------------------------------------------- /ImageToSTL.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGETOSTL_H 2 | #define IMAGETOSTL_H 3 | 4 | #include 5 | #include "ui_ImageToSTL.h" 6 | 7 | // itk class header file 8 | #include "itkImage.h" 9 | #include "itkImageFileReader.h" 10 | #include "itkImageToVTKImageFilter.h" 11 | 12 | // vtk header file 13 | #include "vtkSmartPointer.h" 14 | #include "vtkRenderWindow.h" 15 | #include "vtkRenderer.h" 16 | #include "vtkImageData.h" 17 | #include "vtkInteractorStyleImage.h" 18 | #include "vtkRenderWindowInteractor.h" 19 | #include "vtkImageActor.h" 20 | #include "vtkImageMapToWindowLevelColors.h" 21 | 22 | // vtk class get pixel 23 | #include "vtkInteractorStyleImageGetPixel.h" 24 | 25 | #include 26 | 27 | // Qt class 28 | #include 29 | 30 | #include "STLSet.h" 31 | 32 | // Update coordinate 33 | class vtkEventQtSlotConnect; 34 | 35 | namespace Ui{ 36 | class ImageToSTL; 37 | } 38 | 39 | class ImageToSTL : public QMainWindow 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | ImageToSTL(QWidget *parent = 0, Qt::WFlags flags = 0); 45 | ~ImageToSTL(); 46 | 47 | //itk Standard class typedefs 48 | typedef itk::Image ITKImageType; 49 | typedef itk::ImageFileReader ITKReadType; 50 | typedef itk::ImageToVTKImageFilter ITKtoVTKConnectorType; 51 | 52 | protected: 53 | // void ScribbleEventHandler(vtkObject* caller, long unsigned int eventId, void* callData); 54 | 55 | private: 56 | Ui::ImageToSTL *ui; 57 | 58 | //define reader source image use itk class 59 | ITKReadType::Pointer itkImageReader; 60 | ITKImageType::Pointer itkInputSourceImage; 61 | ITKtoVTKConnectorType::Pointer itkToVtkConnector; 62 | ITKImageType::RegionType::SizeType itkInputSourceImageSize; 63 | 64 | // define vtk variable use vtk class 65 | vtkSmartPointer imageData; 66 | vtkSmartPointer vtkWindowLevel; 67 | vtkSmartPointer imageActor; 68 | vtkSmartPointer vtkRender; 69 | vtkSmartPointer renderWindow; 70 | vtkSmartPointerrenderWinInteractor; 71 | 72 | // Three different interactive style 73 | vtkSmartPointer interactorStyleImage; 74 | vtkSmartPointer interactorStyleGetPixel; 75 | 76 | // Define the current interactive style 77 | vtkInteractorStyleImage *currentInteractorStyle; 78 | 79 | //define file name in Qt 80 | QString inputSourceImageAllName; 81 | QString inputSourceImageName; 82 | 83 | // Input source image's window and level 84 | float inputSourceImageLevel; 85 | float inputSourceImageWindow; 86 | 87 | // Source image prompt message 88 | void inputSourceImagePromptMessage(); 89 | 90 | // Display current pixel's coordinate and value 91 | void displayPixelCoordinateAndValue(); 92 | 93 | // Vtk connect qt 94 | vtkEventQtSlotConnect *vtkConnectQt; 95 | 96 | void vtkImageDataToPly(); 97 | vtkSmartPointer polyData; 98 | double isoValue; 99 | 100 | STLSet *stlParameterSet; 101 | 102 | // Initial window and level 103 | float initialWindow; 104 | float initialLevel; 105 | 106 | void calculateSuitableWinLev(); 107 | 108 | private slots: 109 | // Open source image slot 110 | void openSourceImageSlot(); 111 | 112 | // Save ply 113 | void on_actionSavePly_triggered(); 114 | void on_actionSaveSTL_triggered(); 115 | 116 | // Set source image slice slot 117 | void setSourceImageSliceSlot(int slice); 118 | 119 | // Adjust input source image's window and level 120 | void setSourceImageLevel(); 121 | void setSourceImageWindow(); 122 | 123 | // Update current coordinate 124 | void updateCoordinate(vtkObject* obj); 125 | 126 | // Screenshot 127 | void ViewPaneScreenshot(QVTKWidget *widget); 128 | void on_actionScreenshotLeft_triggered(); 129 | void on_actionScreenshotRight_triggered(); 130 | 131 | // View 132 | void on_actionDisplayPly_triggered(); 133 | 134 | // Patameter set 135 | void on_actionSTLSet_triggered(); 136 | 137 | }; 138 | 139 | #endif // IMAGETOSTL_H 140 | -------------------------------------------------------------------------------- /ImageToSTL.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ImageToSTL.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ImageToSTL 4 | 5 | 6 | 7 | 0 8 | 0 9 | 878 10 | 661 11 | 12 | 13 | 14 | ImageToSTL 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | true 24 | 25 | 26 | Information 27 | 28 | 29 | 30 | 31 | 10 32 | 30 33 | 181 34 | 16 35 | 36 | 37 | 38 | Cursor position(x,y,z): 39 | 40 | 41 | 42 | 43 | 44 | 10 45 | 50 46 | 41 47 | 21 48 | 49 | 50 | 51 | QFrame::Box 52 | 53 | 54 | QFrame::Sunken 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 110 64 | 50 65 | 41 66 | 21 67 | 68 | 69 | 70 | QFrame::Box 71 | 72 | 73 | QFrame::Sunken 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 60 83 | 50 84 | 41 85 | 21 86 | 87 | 88 | 89 | QFrame::Box 90 | 91 | 92 | QFrame::Sunken 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 10 102 | 80 103 | 191 104 | 21 105 | 106 | 107 | 108 | Intensity under cursor: 109 | 110 | 111 | 112 | 113 | 114 | 10 115 | 100 116 | 85 117 | 21 118 | 119 | 120 | 121 | QFrame::Box 122 | 123 | 124 | QFrame::Sunken 125 | 126 | 127 | <html><head/><body><p align="center">Layer</p></body></html> 128 | 129 | 130 | 131 | 132 | 133 | 10 134 | 120 135 | 85 136 | 21 137 | 138 | 139 | 140 | QFrame::Box 141 | 142 | 143 | QFrame::Sunken 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 94 153 | 100 154 | 85 155 | 21 156 | 157 | 158 | 159 | QFrame::Box 160 | 161 | 162 | QFrame::Sunken 163 | 164 | 165 | <html><head/><body><p align="center">Intensity</p></body></html> 166 | 167 | 168 | 169 | 170 | 171 | 94 172 | 120 173 | 85 174 | 21 175 | 176 | 177 | 178 | QFrame::Box 179 | 180 | 181 | QFrame::Sunken 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 10 191 | 160 192 | 60 193 | 21 194 | 195 | 196 | 197 | Level: 198 | 199 | 200 | 201 | 202 | 203 | 10 204 | 185 205 | 60 206 | 21 207 | 208 | 209 | 210 | Window: 211 | 212 | 213 | 214 | 215 | 216 | 70 217 | 160 218 | 85 219 | 21 220 | 221 | 222 | 223 | -66000.000000000000000 224 | 225 | 226 | 66000.000000000000000 227 | 228 | 229 | 10.000000000000000 230 | 231 | 232 | 233 | 234 | 235 | 70 236 | 185 237 | 84 238 | 21 239 | 240 | 241 | 242 | -66000.000000000000000 243 | 244 | 245 | 66000.000000000000000 246 | 247 | 248 | 10.000000000000000 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | Qt::Vertical 257 | 258 | 259 | 260 | 20 261 | 40 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | true 274 | 275 | 276 | Slice selection 277 | 278 | 279 | Qt::Vertical 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | <html><head/><body><p align="center"><span style=" font-size:10pt;">of</span></p></body></html> 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | Qt::Horizontal 316 | 317 | 318 | 319 | 40 320 | 20 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 0 335 | 0 336 | 878 337 | 26 338 | 339 | 340 | 341 | 342 | File 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | ParameterSet 354 | 355 | 356 | 357 | 358 | 359 | Screenshot 360 | 361 | 362 | 363 | 364 | 365 | 366 | View 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | TopToolBarArea 378 | 379 | 380 | false 381 | 382 | 383 | 384 | 385 | 386 | OpenImage 387 | 388 | 389 | 390 | 391 | SaveSTL 392 | 393 | 394 | 395 | 396 | STLSet 397 | 398 | 399 | 400 | 401 | Quit 402 | 403 | 404 | 405 | 406 | ScreenshotLeft 407 | 408 | 409 | 410 | 411 | ScreenshotRight 412 | 413 | 414 | 415 | 416 | DisplayPly 417 | 418 | 419 | 420 | 421 | SavePly 422 | 423 | 424 | 425 | 426 | 427 | 428 | QVTKWidget 429 | QWidget 430 |
QVTKWidget.h
431 |
432 |
433 | 434 | 435 | 436 | 437 | 438 | actionQuit 439 | triggered() 440 | ImageToSTL 441 | close() 442 | 443 | 444 | -1 445 | -1 446 | 447 | 448 | 353 449 | 50 450 | 451 | 452 | 453 | 454 | actionOpenImage 455 | triggered() 456 | ImageToSTL 457 | openSourceImageSlot() 458 | 459 | 460 | -1 461 | -1 462 | 463 | 464 | 456 465 | 54 466 | 467 | 468 | 469 | 470 | sliceSourceImagePosition 471 | valueChanged(int) 472 | ImageToSTL 473 | setSourceImageSliceSlot(int) 474 | 475 | 476 | 415 477 | 115 478 | 479 | 480 | 709 481 | 345 482 | 483 | 484 | 485 | 486 | lineEditSourceImageLevel 487 | valueChanged(double) 488 | ImageToSTL 489 | setSourceImageLevel() 490 | 491 | 492 | 141 493 | 225 494 | 495 | 496 | 243 497 | 303 498 | 499 | 500 | 501 | 502 | lineEditSourceImageWindow 503 | valueChanged(double) 504 | ImageToSTL 505 | setSourceImageWindow() 506 | 507 | 508 | 119 509 | 247 510 | 511 | 512 | 133 513 | 348 514 | 515 | 516 | 517 | 518 | 519 | openSourceImageSlot() 520 | setSourceImageSliceSlot(int) 521 | setSourceImageLevel() 522 | setSourceImageWindow() 523 | 524 |
525 | -------------------------------------------------------------------------------- /Medical Image Data/ReadMe: -------------------------------------------------------------------------------- 1 | heart and nucleon image file 2 | -------------------------------------------------------------------------------- /Medical Image Data/heart.mhd: -------------------------------------------------------------------------------- 1 | NDims = 3 2 | DimSize = 125 154 145 3 | ElementType = MET_UCHAR 4 | ElementSpacing = 0.0127651 0.0127389 0.0128079 5 | ElementByteOrderMSB = False 6 | ElementDataFile = heart.raw 7 | -------------------------------------------------------------------------------- /Medical Image Data/heart.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Medical Image Data/heart.raw -------------------------------------------------------------------------------- /Medical Image Data/nucleon.mhd: -------------------------------------------------------------------------------- 1 | NDims = 3 2 | DimSize = 41 41 41 3 | ElementType = MET_UCHAR 4 | ElementSpacing = 1.0 1.0 1.0 5 | ElementByteOrderMSB = False 6 | ElementDataFile = nucleon.raw 7 | -------------------------------------------------------------------------------- /Medical Image Data/nucleon.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Medical Image Data/nucleon.raw -------------------------------------------------------------------------------- /MedicalImageTool.cpp: -------------------------------------------------------------------------------- 1 | #include "MedicalImageTool.h" 2 | 3 | // Itk class 4 | #include "itkImageFileWriter.h" 5 | 6 | // Vtk class 7 | #include "vtkResliceCursorCallback.h" 8 | 9 | #include 10 | #include 11 | #include "vtkImageFlip.h" 12 | 13 | #include "vtkSmartPointer.h" 14 | #include "vtkCellPicker.h" 15 | #include "vtkResliceCursorLineRepresentation.h" 16 | #include "vtkResliceImageViewer.h" 17 | #include "vtkResliceCursorThickLineRepresentation.h" 18 | #include "vtkResliceCursorWidget.h" 19 | #include "vtkResliceCursorActor.h" 20 | #include "vtkResliceCursorPolyDataAlgorithm.h" 21 | #include "vtkResliceCursor.h" 22 | 23 | #include "vtkMetaImageReader.h" 24 | #include "vtkDICOMImageReader.h" 25 | #include "vtkVolume16Reader.h" 26 | 27 | #include "vtkProperty.h" 28 | #include "vtkPlane.h" 29 | #include "vtkImageData.h" 30 | #include "vtkCommand.h" 31 | #include "vtkPlaneSource.h" 32 | #include "vtkLookupTable.h" 33 | #include "vtkImageMapToWindowLevelColors.h" 34 | #include "vtkInteractorStyleImage.h" 35 | #include "vtkImageSlabReslice.h" 36 | #include "vtkBoundedPlanePointPlacer.h" 37 | #include "vtkDistanceRepresentation.h" 38 | #include "vtkHandleRepresentation.h" 39 | 40 | #include "vtkDistanceRepresentation2D.h" 41 | #include "vtkPointHandleRepresentation3D.h" 42 | #include "vtkPointHandleRepresentation2D.h" 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | // Qt class 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | MedicalImageTool::MedicalImageTool(QWidget *parent, Qt::WFlags flags) 56 | : QMainWindow(parent, flags), ui(new Ui::MedicalImageTool) 57 | { 58 | ui->setupUi(this); 59 | this->setWindowTitle("MedicalImageTool"); 60 | 61 | // Initialize variable 62 | inputItkImage = ItkImageType::New(); 63 | itkReader = ItkReaderType::New(); 64 | itkToVtkConnector = ItkToVtkType::New(); 65 | inputVtkImage = vtkSmartPointer::New(); 66 | 67 | crosshairEdit = new Crosshair; 68 | aboutHelp = new About; 69 | distMeasEdit = new DistanceMeasurement; 70 | 71 | srcImageRenderer = new VolumeRenderer; 72 | stlFileFilter = new ImageToSTL; 73 | 74 | connect(this->crosshairEdit->ui->resliceModeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(resliceMode(int))); 75 | connect(this->crosshairEdit->ui->thickModeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(thickMode(int))); 76 | this->crosshairEdit->ui->thickModeCheckBox->setEnabled(0); 77 | connect(this->crosshairEdit->ui->resetButton, SIGNAL(pressed()), this, SLOT(ResetViews())); 78 | connect(this->distMeasEdit->ui->pushButtonDistMeasAxial, SIGNAL(pressed()), this, SLOT(AddDistanceMeasurementToAxial())); 79 | connect(this->distMeasEdit->ui->pushButtonDistMeasSagital, SIGNAL(pressed()), this, SLOT(AddDistanceMeasurementToSagital())); 80 | connect(this->distMeasEdit->ui->pushButtonDistMeasCoronal, SIGNAL(pressed()), this, SLOT(AddDistanceMeasurementToCoronal())); 81 | connect(this->distMeasEdit->ui->pushButtonDistMeas3DView, SIGNAL(pressed()), this, SLOT(AddDistanceMeasurementTo3DView())); 82 | 83 | } 84 | 85 | MedicalImageTool::~MedicalImageTool() 86 | { 87 | delete ui; 88 | delete crosshairEdit; 89 | delete aboutHelp; 90 | delete srcImageRenderer; 91 | delete stlFileFilter; 92 | } 93 | 94 | // Close the program 95 | void MedicalImageTool::on_actionExit_triggered() 96 | { 97 | this->close(); 98 | } 99 | 100 | // Open image 101 | void MedicalImageTool::on_actionOpenImage_triggered() 102 | { 103 | // Get the input image name 104 | m_InputImageAllName = QFileDialog::getOpenFileName(this, 105 | "Open Image", "../Image", 106 | tr("Image Files(*.mhd *.mha *.dcm *.hdr *.img *nii *jpg *jpeg *png *bmp)")); 107 | 108 | if (m_InputImageAllName.isEmpty()) 109 | { 110 | return; 111 | } 112 | 113 | QFileInfo fileInfo = QFileInfo(this->m_InputImageAllName); 114 | this->m_InputImageName = fileInfo.fileName(); 115 | this->m_InputImageSuffixName = fileInfo.suffix(); 116 | this->m_InputPath = fileInfo.absolutePath(); 117 | 118 | itkReader->SetFileName(this->m_InputImageAllName.toStdString()); 119 | itkReader->Update(); 120 | inputItkImage = itkReader->GetOutput(); 121 | itkToVtkConnector->SetInput(inputItkImage); 122 | itkToVtkConnector->Update(); 123 | 124 | vtkSmartPointer vtkFlipFiter = 125 | vtkSmartPointer::New(); 126 | vtkFlipFiter->SetInputData(itkToVtkConnector->GetOutput()); 127 | vtkFlipFiter->SetFilteredAxes(1); 128 | vtkFlipFiter->Update(); 129 | inputVtkImage = vtkFlipFiter->GetOutput(); 130 | 131 | LoadImage(m_InputImageAllName); 132 | } 133 | 134 | void MedicalImageTool::LoadImage(QString fileName) 135 | { 136 | vtkSmartPointer reader 137 | = vtkSmartPointer::New(); 138 | reader->SetFileName(fileName.toStdString().data()); 139 | reader->Update(); 140 | 141 | int imageDims[3]; 142 | reader->GetOutput()->GetDimensions(imageDims); 143 | 144 | for (int i = 0; i < 3; i++) 145 | { 146 | riw[i] = vtkSmartPointer< vtkResliceImageViewer >::New(); 147 | } 148 | 149 | this->ui->qvtkWidgetSagitalPlane->SetRenderWindow(riw[0]->GetRenderWindow()); 150 | riw[0]->SetupInteractor( 151 | this->ui->qvtkWidgetSagitalPlane->GetRenderWindow()->GetInteractor()); 152 | 153 | this->ui->qvtkWidgetCoronalPlane->SetRenderWindow(riw[1]->GetRenderWindow()); 154 | riw[1]->SetupInteractor( 155 | this->ui->qvtkWidgetCoronalPlane->GetRenderWindow()->GetInteractor()); 156 | 157 | this->ui->qvtkWidgetAxialPlane->SetRenderWindow(riw[2]->GetRenderWindow()); 158 | riw[2]->SetupInteractor( 159 | this->ui->qvtkWidgetAxialPlane->GetRenderWindow()->GetInteractor()); 160 | 161 | for (int i = 0; i < 3; i++) 162 | { 163 | // make them all share the same reslice cursor object. 164 | vtkResliceCursorLineRepresentation *rep = 165 | vtkResliceCursorLineRepresentation::SafeDownCast( 166 | riw[i]->GetResliceCursorWidget()->GetRepresentation()); 167 | riw[i]->SetResliceCursor(riw[0]->GetResliceCursor()); 168 | 169 | rep->GetResliceCursorActor()-> 170 | GetCursorAlgorithm()->SetReslicePlaneNormal(i); 171 | 172 | riw[i]->SetInputData(reader->GetOutput()); 173 | riw[i]->SetSliceOrientation(i); 174 | riw[i]->SetResliceModeToAxisAligned(); 175 | } 176 | 177 | vtkSmartPointer picker = 178 | vtkSmartPointer::New(); 179 | picker->SetTolerance(0.005); 180 | 181 | vtkSmartPointer ipwProp = 182 | vtkSmartPointer::New(); 183 | 184 | vtkSmartPointer< vtkRenderer > ren = 185 | vtkSmartPointer< vtkRenderer >::New(); 186 | 187 | this->ui->qvtkWidget3DView->GetRenderWindow()->AddRenderer(ren); 188 | vtkRenderWindowInteractor *iren = this->ui->qvtkWidget3DView->GetInteractor(); 189 | 190 | for (int i = 0; i < 3; i++) 191 | { 192 | planeWidget[i] = vtkSmartPointer::New(); 193 | planeWidget[i]->SetInteractor(iren); 194 | planeWidget[i]->SetPicker(picker); 195 | planeWidget[i]->RestrictPlaneToVolumeOn(); 196 | double color[3] = { 0, 0, 0 }; 197 | color[i] = 1; 198 | planeWidget[i]->GetPlaneProperty()->SetColor(color); 199 | 200 | color[0] /= 4.0; 201 | color[1] /= 4.0; 202 | color[2] /= 4.0; 203 | riw[i]->GetRenderer()->SetBackground(color); 204 | 205 | planeWidget[i]->SetTexturePlaneProperty(ipwProp); 206 | planeWidget[i]->TextureInterpolateOff(); 207 | planeWidget[i]->SetResliceInterpolateToLinear(); 208 | planeWidget[i]->SetInputConnection(reader->GetOutputPort()); 209 | planeWidget[i]->SetPlaneOrientation(i); 210 | planeWidget[i]->SetSliceIndex(imageDims[i] / 2); 211 | planeWidget[i]->DisplayTextOn(); 212 | planeWidget[i]->SetDefaultRenderer(ren); 213 | planeWidget[i]->SetWindowLevel(1358, -27); 214 | planeWidget[i]->On(); 215 | planeWidget[i]->InteractionOn(); 216 | } 217 | 218 | vtkSmartPointer cbk = 219 | vtkSmartPointer::New(); 220 | 221 | for (int i = 0; i < 3; i++) 222 | { 223 | cbk->IPW[i] = planeWidget[i]; 224 | cbk->RCW[i] = riw[i]->GetResliceCursorWidget(); 225 | riw[i]->GetResliceCursorWidget()->AddObserver( 226 | vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk); 227 | riw[i]->GetResliceCursorWidget()->AddObserver( 228 | vtkResliceCursorWidget::WindowLevelEvent, cbk); 229 | riw[i]->GetResliceCursorWidget()->AddObserver( 230 | vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk); 231 | riw[i]->GetResliceCursorWidget()->AddObserver( 232 | vtkResliceCursorWidget::ResetCursorEvent, cbk); 233 | riw[i]->GetInteractorStyle()->AddObserver( 234 | vtkCommand::WindowLevelEvent, cbk); 235 | 236 | // Make them all share the same color map. 237 | riw[i]->SetLookupTable(riw[0]->GetLookupTable()); 238 | planeWidget[i]->GetColorMap()->SetLookupTable(riw[0]->GetLookupTable()); 239 | //planeWidget[i]->GetColorMap()->SetInput(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap()->GetInput()); 240 | planeWidget[i]->SetColorMap(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap()); 241 | 242 | } 243 | 244 | this->ui->qvtkWidgetSagitalPlane->show(); 245 | this->ui->qvtkWidgetCoronalPlane->show(); 246 | this->ui->qvtkWidgetAxialPlane->show(); 247 | } 248 | 249 | void MedicalImageTool::on_actionSaveAs_triggered() 250 | { 251 | if (m_InputImageAllName.isEmpty()) 252 | { 253 | QMessageBox::information(this, "Prompt Message", "Please input a image !"); 254 | return; 255 | } 256 | QString fileName = QFileDialog::getSaveFileName(this, "Save Image", "", "Image Files (*.mhd *.mha *.dcm *.img *.hdr *.nii)"); 257 | if (fileName.isEmpty()) 258 | { 259 | QMessageBox::information(this, "Prompt Message", "Please input a file name !"); 260 | return; 261 | } 262 | 263 | typedef itk::ImageFileWriter WriterType; 264 | WriterType::Pointer writer = WriterType::New(); 265 | writer->SetFileName( fileName.toStdString() ); 266 | writer->SetInput(inputItkImage); 267 | writer->Write(); 268 | 269 | } 270 | 271 | void MedicalImageTool::on_actionOpenSTL_triggered() 272 | { 273 | // if (m_InputImageAllName.isEmpty()) 274 | // { 275 | // QMessageBox::information(this, "Prompt Message", "Please input a image !"); 276 | // return; 277 | // } 278 | this->stlFileFilter->show(); 279 | } 280 | 281 | void MedicalImageTool::on_actionCrosshair_triggered() 282 | { 283 | this->crosshairEdit->show(); 284 | } 285 | 286 | //-------------------------------------------------------------------------------------- 287 | // Edit function 288 | void MedicalImageTool::resliceMode(int mode) 289 | { 290 | this->crosshairEdit->ui->thickModeCheckBox->setEnabled(mode ? 1 : 0); 291 | this->crosshairEdit->ui->blendModeGroupBox->setEnabled(mode ? 1 : 0); 292 | 293 | for (int i = 0; i < 3; i++) 294 | { 295 | riw[i]->SetResliceMode(mode ? 1 : 0); 296 | riw[i]->GetRenderer()->ResetCamera(); 297 | riw[i]->Render(); 298 | } 299 | } 300 | 301 | void MedicalImageTool::thickMode(int mode) 302 | { 303 | for (int i = 0; i < 3; i++) 304 | { 305 | riw[i]->SetThickMode(mode ? 1 : 0); 306 | riw[i]->Render(); 307 | } 308 | } 309 | 310 | void MedicalImageTool::ResetViews() 311 | { 312 | // Reset the reslice image views 313 | for (int i = 0; i < 3; i++) 314 | { 315 | riw[i]->Reset(); 316 | } 317 | 318 | // Also sync the Image plane widget on the 3D top right view with any 319 | // changes to the reslice cursor. 320 | for (int i = 0; i < 3; i++) 321 | { 322 | vtkPlaneSource *ps = static_cast( 323 | planeWidget[i]->GetPolyDataAlgorithm()); 324 | ps->SetNormal(riw[0]->GetResliceCursor()->GetPlane(i)->GetNormal()); 325 | ps->SetCenter(riw[0]->GetResliceCursor()->GetPlane(i)->GetOrigin()); 326 | 327 | // If the reslice plane has modified, update it on the 3D widget 328 | this->planeWidget[i]->UpdatePlacement(); 329 | } 330 | 331 | // Render in response to changes. 332 | this->riw[0]->Render(); 333 | this->riw[1]->Render(); 334 | this->riw[2]->Render(); 335 | } 336 | 337 | void MedicalImageTool::on_actionDistanceMeasure_triggered() 338 | { 339 | this->distMeasEdit->show(); 340 | } 341 | 342 | void MedicalImageTool::AddDistanceMeasurementToAxial() 343 | { 344 | this->AddDistanceMeasurementToView(2); 345 | } 346 | 347 | void MedicalImageTool::AddDistanceMeasurementToSagital() 348 | { 349 | this->AddDistanceMeasurementToView(0); 350 | } 351 | 352 | void MedicalImageTool::AddDistanceMeasurementToCoronal() 353 | { 354 | this->AddDistanceMeasurementToView(1); 355 | } 356 | 357 | void MedicalImageTool::AddDistanceMeasurementTo3DView() 358 | { 359 | // this->AddDistanceMeasurementToView(3); 360 | } 361 | 362 | void MedicalImageTool::AddDistanceMeasurementToView(int i) 363 | { 364 | // remove existing widgets. 365 | if (this->DistanceWidget[i]) 366 | { 367 | this->DistanceWidget[i]->SetEnabled(0); 368 | this->DistanceWidget[i] = NULL; 369 | } 370 | 371 | // add new widget 372 | this->DistanceWidget[i] = vtkSmartPointer< vtkDistanceWidget >::New(); 373 | this->DistanceWidget[i]->SetInteractor( 374 | this->riw[i]->GetResliceCursorWidget()->GetInteractor()); 375 | 376 | // Set a priority higher than our reslice cursor widget 377 | this->DistanceWidget[i]->SetPriority( 378 | this->riw[i]->GetResliceCursorWidget()->GetPriority() + 0.01); 379 | 380 | vtkSmartPointer< vtkPointHandleRepresentation2D > handleRep = 381 | vtkSmartPointer< vtkPointHandleRepresentation2D >::New(); 382 | vtkSmartPointer< vtkDistanceRepresentation2D > distanceRep = 383 | vtkSmartPointer< vtkDistanceRepresentation2D >::New(); 384 | distanceRep->SetHandleRepresentation(handleRep); 385 | this->DistanceWidget[i]->SetRepresentation(distanceRep); 386 | distanceRep->InstantiateHandleRepresentation(); 387 | distanceRep->GetPoint1Representation()->SetPointPlacer(riw[i]->GetPointPlacer()); 388 | distanceRep->GetPoint2Representation()->SetPointPlacer(riw[i]->GetPointPlacer()); 389 | 390 | // Add the distance to the list of widgets whose visibility is managed based 391 | // on the reslice plane by the ResliceImageViewerMeasurements class 392 | this->riw[i]->GetMeasurements()->AddItem(this->DistanceWidget[i]); 393 | 394 | this->DistanceWidget[i]->CreateDefaultRepresentation(); 395 | this->DistanceWidget[i]->EnabledOn(); 396 | } 397 | 398 | //-------------------------------------------------------------------------------------- 399 | // Screenshot 400 | void MedicalImageTool::ViewPaneScreenshot(QVTKWidget *widget) 401 | { 402 | QString fileName = QFileDialog::getSaveFileName(this, "Save Screenshot", "", "Pircture Files (*.png *.jpg)"); 403 | if (fileName.isEmpty()) 404 | { 405 | return; 406 | } 407 | 408 | vtkSmartPointer windowToImageFilter = 409 | vtkSmartPointer::New(); 410 | windowToImageFilter->SetInput(widget->GetRenderWindow()); 411 | //windowToImageFilter->SetMagnification(3); 412 | windowToImageFilter->Update(); 413 | 414 | vtkSmartPointer writer = 415 | vtkSmartPointer::New(); 416 | writer->SetFileName(fileName.toStdString().c_str()); 417 | writer->SetInputConnection(windowToImageFilter->GetOutputPort()); 418 | writer->Write(); 419 | } 420 | void MedicalImageTool::on_actionScreenshotUpperLeft_triggered() 421 | { 422 | this->ViewPaneScreenshot(this->ui->qvtkWidgetAxialPlane); 423 | } 424 | 425 | void MedicalImageTool::on_actionScreenshotUpperRight_triggered() 426 | { 427 | this->ViewPaneScreenshot(this->ui->qvtkWidgetSagitalPlane); 428 | } 429 | 430 | void MedicalImageTool::on_actionScreenshotLowerLeft_triggered() 431 | { 432 | this->ViewPaneScreenshot(this->ui->qvtkWidgetCoronalPlane); 433 | } 434 | 435 | void MedicalImageTool::on_actionScreenshotLowerRight_triggered() 436 | { 437 | this->ViewPaneScreenshot(this->ui->qvtkWidget3DView); 438 | } 439 | 440 | //----------------------------------------------------------------------------------------------------- 441 | // Volume Renderer 442 | void MedicalImageTool::on_actionGPUVolumeRenderer_triggered() 443 | { 444 | if (m_InputImageAllName.isEmpty()) 445 | { 446 | QMessageBox::information(this, "Prompt Message", "Please select a image !"); 447 | return; 448 | } 449 | 450 | this->srcImageRenderer->show(); 451 | this->srcImageRenderer->SetInputImage(m_InputImageAllName); 452 | } 453 | 454 | //----------------------------------------------------------------------------------------------------- 455 | // Help function 456 | void MedicalImageTool::on_actionAboutProgram_triggered() 457 | { 458 | this->aboutHelp->show(); 459 | } 460 | -------------------------------------------------------------------------------- /MedicalImageTool.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDICALIMAGETOOL_H 2 | #define MEDICALIMAGETOOL_H 3 | 4 | #include 5 | #include "ui_MedicalImageTool.h" 6 | 7 | // Itk class 8 | #include "itkImage.h" 9 | #include "itkImageFileReader.h" 10 | #include "itkImageToVTKImageFilter.h" 11 | 12 | // Vtk class 13 | #include "vtkSmartPointer.h" 14 | #include "vtkImageData.h" 15 | #include "vtkResliceImageViewer.h" 16 | #include "vtkImagePlaneWidget.h" 17 | #include "vtkDistanceWidget.h" 18 | #include "vtkResliceImageViewerMeasurements.h" 19 | #include "VolumeRenderer.h" 20 | 21 | // Qt class 22 | #include "Crosshair.h" 23 | #include "DistanceMeasurement.h" 24 | #include "About.h" 25 | #include "ImageToSTL.h" 26 | 27 | #include "QVTKWidget.h" 28 | 29 | namespace Ui 30 | { 31 | class MedicalImageTool; 32 | } 33 | 34 | class MedicalImageTool : public QMainWindow 35 | { 36 | Q_OBJECT 37 | 38 | public: 39 | MedicalImageTool(QWidget *parent = 0, Qt::WFlags flags = 0); 40 | ~MedicalImageTool(); 41 | 42 | typedef itk::Image ItkImageType; 43 | typedef itk::ImageFileReader ItkReaderType; 44 | typedef itk::ImageToVTKImageFilter ItkToVtkType; 45 | 46 | protected slots: 47 | 48 | // Edit function 49 | virtual void resliceMode(int); 50 | virtual void thickMode(int); 51 | virtual void ResetViews(); 52 | 53 | virtual void AddDistanceMeasurementToAxial(); 54 | virtual void AddDistanceMeasurementToSagital(); 55 | virtual void AddDistanceMeasurementToCoronal(); 56 | virtual void AddDistanceMeasurementTo3DView(); 57 | virtual void AddDistanceMeasurementToView(int); 58 | 59 | private slots: 60 | // File function 61 | void on_actionExit_triggered(); 62 | void on_actionOpenImage_triggered(); 63 | 64 | void on_actionSaveAs_triggered(); 65 | void on_actionOpenSTL_triggered(); 66 | 67 | // Edit function 68 | void on_actionCrosshair_triggered(); 69 | void on_actionDistanceMeasure_triggered(); 70 | 71 | void on_actionScreenshotUpperLeft_triggered(); 72 | void on_actionScreenshotUpperRight_triggered(); 73 | void on_actionScreenshotLowerLeft_triggered(); 74 | void on_actionScreenshotLowerRight_triggered(); 75 | 76 | // Help function 77 | void on_actionAboutProgram_triggered(); 78 | 79 | // GPU Renderer 80 | void on_actionGPUVolumeRenderer_triggered(); 81 | 82 | private: 83 | Ui::MedicalImageTool *ui; 84 | 85 | // Itk variable 86 | ItkImageType::Pointer inputItkImage; 87 | ItkReaderType::Pointer itkReader; 88 | ItkToVtkType::Pointer itkToVtkConnector; 89 | 90 | // Vtk variable 91 | vtkSmartPointer inputVtkImage; 92 | 93 | // Qt variable 94 | QString m_InputImageAllName; 95 | QString m_InputImageName; 96 | QString m_InputImageSuffixName; 97 | QString m_InputPath; 98 | 99 | vtkSmartPointer< vtkResliceImageViewer > riw[3]; 100 | vtkSmartPointer< vtkImagePlaneWidget > planeWidget[3]; 101 | vtkSmartPointer< vtkDistanceWidget > DistanceWidget[3]; 102 | vtkSmartPointer< vtkResliceImageViewerMeasurements > ResliceMeasurements; 103 | 104 | void LoadImage(QString fileName); 105 | 106 | Crosshair *crosshairEdit; 107 | DistanceMeasurement *distMeasEdit; 108 | About *aboutHelp; 109 | VolumeRenderer * srcImageRenderer; 110 | ImageToSTL *stlFileFilter; 111 | 112 | // Screenshot 113 | void ViewPaneScreenshot(QVTKWidget *widget); 114 | }; 115 | 116 | #endif // MEDICALIMAGETOOL_H 117 | -------------------------------------------------------------------------------- /MedicalImageTool.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/exit.png 4 | Resources/fileopen.png 5 | Resources/filesave.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /MedicalImageTool.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MedicalImageTool 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1091 10 | 697 11 | 12 | 13 | 14 | MedicalImageTool 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 0 40 | 0 41 | 1091 42 | 26 43 | 44 | 45 | 46 | 47 | File 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Edit 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Help 71 | 72 | 73 | 74 | 75 | 76 | Renderer 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | TopToolBarArea 88 | 89 | 90 | false 91 | 92 | 93 | 94 | 95 | 96 | 97 | :/MedicalImageTool/Resources/fileopen.png:/MedicalImageTool/Resources/fileopen.png 98 | 99 | 100 | OpenImage 101 | 102 | 103 | 104 | 105 | 106 | :/MedicalImageTool/Resources/exit.png:/MedicalImageTool/Resources/exit.png 107 | 108 | 109 | Exit 110 | 111 | 112 | 113 | 114 | Crosshair 115 | 116 | 117 | 118 | 119 | DistanceMeasure 120 | 121 | 122 | 123 | 124 | AboutProgram 125 | 126 | 127 | 128 | 129 | GPUVolumeRenderer 130 | 131 | 132 | 133 | 134 | 135 | :/MedicalImageTool/Resources/filesave.png:/MedicalImageTool/Resources/filesave.png 136 | 137 | 138 | SaveAs 139 | 140 | 141 | 142 | 143 | ScreenshotUpperLeft 144 | 145 | 146 | 147 | 148 | ScreenshotLowerLeft 149 | 150 | 151 | 152 | 153 | ScreenshotUpperRight 154 | 155 | 156 | 157 | 158 | ScreenshotLowerRight 159 | 160 | 161 | 162 | 163 | OpenSTL 164 | 165 | 166 | 167 | 168 | 169 | 170 | QVTKWidget 171 | QWidget 172 |
QVTKWidget.h
173 |
174 |
175 | 176 | 177 | 178 | 179 |
180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Medical-Image-Tool 2 | Using ITK, VTK, Qt to browse medical images and other functions. 3 | The source code has been compiled with Qt 4.8.5, ITK 4.9, VTK 6.3, Visual Studio 2010, CMake 2.12 and X64 Window7. 4 | 5 | **CMake settings for compiling VTK** 6 | Note that compiler compilation cannot be done by default compilation when compiling VTK. 7 | You need to set the following settings 8 | 9 | set(VTK_QT_VERSION 4 CACHE STRING "Qt version") 10 | set(VTK_NO_LIBRARY_VERSION ON CACHE BOOL "VTK_NO_LIBRARY_VERSION") 11 | set(VTK_Group_Qt ON CACHE BOOL "VTK_Group_Qt") 12 | set(Module_vtkGUISupportQt ON CACHE BOOL "Module_vtkGUISupportQt") 13 | set(Module_vtkGUISupportQtOpenGL ON CACHE BOOL "Module_vtkGUISupportQtOpenGL") 14 | set(Module_vtkRenderingQt ON CACHE BOOL "Module_vtkRenderingQt") 15 | set(BUILD_TESTING OFF CACHE BOOL "BUILD_TESTING") 16 | set(VTK_RENDERING_BACKEND_DEFAULT "OpenGL") 17 | # Result 1 18 | ![image](https://github.com/wangdemon/Medical-Image-Tool/blob/master/Result/pic1.png) 19 | # Result 2 20 | ![image](https://github.com/wangdemon/Medical-Image-Tool/blob/master/Result/pic2.png) 21 | # Result 3 22 | ![image](https://github.com/wangdemon/Medical-Image-Tool/blob/master/Result/pic3.png) 23 | -------------------------------------------------------------------------------- /Resources/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/1.png -------------------------------------------------------------------------------- /Resources/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/2.png -------------------------------------------------------------------------------- /Resources/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/3.jpg -------------------------------------------------------------------------------- /Resources/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/4.png -------------------------------------------------------------------------------- /Resources/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/5.png -------------------------------------------------------------------------------- /Resources/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/6.png -------------------------------------------------------------------------------- /Resources/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/7.png -------------------------------------------------------------------------------- /Resources/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/8.jpg -------------------------------------------------------------------------------- /Resources/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/9.png -------------------------------------------------------------------------------- /Resources/README: -------------------------------------------------------------------------------- 1 | Qt's project resource file 2 | -------------------------------------------------------------------------------- /Resources/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/exit.png -------------------------------------------------------------------------------- /Resources/fileopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/fileopen.png -------------------------------------------------------------------------------- /Resources/filesave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/filesave.png -------------------------------------------------------------------------------- /Resources/splashscreen.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Resources/splashscreen.PNG -------------------------------------------------------------------------------- /Result/README: -------------------------------------------------------------------------------- 1 | The program running results 2 | -------------------------------------------------------------------------------- /Result/pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Result/pic1.png -------------------------------------------------------------------------------- /Result/pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Result/pic2.png -------------------------------------------------------------------------------- /Result/pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Result/pic3.png -------------------------------------------------------------------------------- /STLSet.cpp: -------------------------------------------------------------------------------- 1 | #include "STLSet.h" 2 | 3 | STLSet::STLSet(QWidget *parent, Qt::WFlags flags) 4 | : QWidget(parent, flags), ui(new Ui::STLSet) 5 | { 6 | ui->setupUi(this); 7 | this->setWindowTitle("Image To Ply Set Parameter"); 8 | this->setMaximumSize(488,251); 9 | this->setMinimumSize(488,251); 10 | } 11 | 12 | STLSet::~STLSet() 13 | { 14 | delete ui; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /STLSet.h: -------------------------------------------------------------------------------- 1 | #ifndef STLSET_H 2 | #define STLSET_H 3 | 4 | #include 5 | #include "ui_STLSet.h" 6 | 7 | namespace Ui{ 8 | class STLSet; 9 | }; 10 | 11 | class STLSet : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | STLSet(QWidget *parent = 0, Qt::WFlags flags = 0); 17 | ~STLSet(); 18 | 19 | Ui::STLSet *ui; 20 | private: 21 | // Ui::STLSet *ui; 22 | }; 23 | 24 | #endif // STLSET_H 25 | -------------------------------------------------------------------------------- /STLSet.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/9.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /STLSet.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | STLSet 4 | 5 | 6 | 7 | 0 8 | 0 9 | 488 10 | 251 11 | 12 | 13 | 14 | STLSet 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 0 23 | 0 24 | 488 25 | 251 26 | 27 | 28 | 29 | image: url(:/STLSet/Resources/9.png); 30 | 31 | 32 | QFrame::NoFrame 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 270 42 | 20 43 | 165 44 | 21 45 | 46 | 47 | 48 | 49 | 50 | 51 | 20 52 | 20 53 | 200 54 | 20 55 | 56 | 57 | 58 | <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">Image To Ply iosValue:</span></p></body></html> 59 | 60 | 61 | 62 | 63 | 64 | 20 65 | 70 66 | 220 67 | 20 68 | 69 | 70 | 71 | <html><head/><body><p><span style=" font-weight:600; color:#0000ff;">Source Image Background:</span></p></body></html> 72 | 73 | 74 | 75 | 76 | 77 | 20 78 | 120 79 | 150 80 | 20 81 | 82 | 83 | 84 | <html><head/><body><p><span style=" font-weight:600; color:#00aa00;">Ply Background:</span></p></body></html> 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Slicer/README: -------------------------------------------------------------------------------- 1 | Volume renderer of Slicer 2 | -------------------------------------------------------------------------------- /Slicer/Slicer.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/874ab4b0eca55f55eeeb81fe7a09a287a7f7c3d3/Slicer/Slicer.rar -------------------------------------------------------------------------------- /VolumeRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "VolumeRenderer.h" 2 | 3 | // Vtk class 4 | #include 5 | #include 6 | 7 | VolumeRenderer::VolumeRenderer(QWidget *parent, Qt::WFlags flags) 8 | : QMainWindow(parent, flags), ui(new Ui::VolumeRenderer) 9 | { 10 | ui->setupUi(this); 11 | 12 | // add VTK widgets 13 | ui->verticalLayout->addWidget(&widget); 14 | ui->verticalLayout_2->addWidget(&volumePropertywidget); 15 | 16 | // set up interactor 17 | interactor = vtkSmartPointer::New(); 18 | interactor->SetRenderWindow(widget.GetRenderWindow()); 19 | 20 | // allow the user to interactively manipulate (rotate, pan, etc.) the camera, the viewpoint of the scene. 21 | auto style = vtkSmartPointer::New(); 22 | interactor->SetInteractorStyle(style); 23 | } 24 | 25 | void VolumeRenderer::on_actionOpenImage_triggered() 26 | { 27 | // show file dialog. change filename only when the new filename is not empty. 28 | QString filter("Meta image file (*.mhd *.mha)"); 29 | QString filename_backup = filename; 30 | filename_backup = QFileDialog::getOpenFileName(this, QString(tr("Open a volume data set")), filename_backup, filter); 31 | if (!filename_backup.trimmed().isEmpty()) 32 | { 33 | filename = filename_backup; 34 | } 35 | else 36 | { 37 | return; 38 | } 39 | 40 | this->SetInputImage(filename); 41 | } 42 | 43 | VolumeRenderer::~VolumeRenderer() 44 | { 45 | delete ui; 46 | } 47 | 48 | void VolumeRenderer::on_action_Exit_triggered() 49 | { 50 | this->close(); 51 | } 52 | 53 | void VolumeRenderer::on_action_About_triggered() 54 | { 55 | QMessageBox msgBox; 56 | msgBox.setText(QString::fromUtf8("Volume Renderer")); 57 | msgBox.exec(); 58 | } 59 | 60 | void VolumeRenderer::SetInputImage(QString inputFileName) 61 | { 62 | this->filename = inputFileName; 63 | 64 | // show filename on window title 65 | this->setWindowTitle(QString::fromUtf8("Volume Renderer - ") + filename); 66 | 67 | QByteArray ba = filename.toLocal8Bit(); 68 | const char *filename_str = ba.data(); 69 | 70 | #if 1 71 | // read Meta Image (.mhd or .mha) files 72 | auto reader = vtkSmartPointer::New(); 73 | reader->SetFileName(filename_str); 74 | #elif 1 75 | // read a series of raw files in the specified folder 76 | auto reader = vtkSmartPointer::New(); 77 | reader->SetDataDimensions(512, 512); 78 | reader->SetImageRange(1, 361); 79 | reader->SetDataByteOrderToBigEndian(); 80 | reader->SetFilePrefix(filename_str); 81 | reader->SetFilePattern("%s%d"); 82 | reader->SetDataSpacing(1, 1, 1); 83 | #else 84 | // read NRRD files 85 | vtkNew reader; 86 | if (!reader->CanReadFile(filename_str)) 87 | { 88 | std::cerr << "Reader reports " << filename_str << " cannot be read."; 89 | exit(EXIT_FAILURE); 90 | } 91 | reader->SetFileName(filename_str); 92 | reader->Update(); 93 | #endif 94 | 95 | // scale the volume data to unsigned char (0-255) before passing it to volume mapper 96 | auto shiftScale = vtkSmartPointer::New(); 97 | shiftScale->SetInputConnection(reader->GetOutputPort()); 98 | shiftScale->SetOutputScalarTypeToUnsignedChar(); 99 | 100 | // Create transfer mapping scalar value to opacity. 101 | auto opacityTransferFunction = vtkSmartPointer::New(); 102 | opacityTransferFunction->AddPoint(0.0, 0.0); 103 | opacityTransferFunction->AddPoint(36.0, 0.125); 104 | opacityTransferFunction->AddPoint(72.0, 0.25); 105 | opacityTransferFunction->AddPoint(108.0, 0.375); 106 | opacityTransferFunction->AddPoint(144.0, 0.5); 107 | opacityTransferFunction->AddPoint(180.0, 0.625); 108 | opacityTransferFunction->AddPoint(216.0, 0.75); 109 | opacityTransferFunction->AddPoint(255.0, 0.875); 110 | 111 | // Create transfer mapping scalar value to color. 112 | auto colorTransferFunction = vtkSmartPointer::New(); 113 | colorTransferFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0); 114 | colorTransferFunction->AddRGBPoint(36.0, 1.0, 0.0, 0.0); 115 | colorTransferFunction->AddRGBPoint(72.0, 1.0, 1.0, 0.0); 116 | colorTransferFunction->AddRGBPoint(108.0, 0.0, 1.0, 0.0); 117 | colorTransferFunction->AddRGBPoint(144.0, 0.0, 1.0, 1.0); 118 | colorTransferFunction->AddRGBPoint(180.0, 0.0, 0.0, 1.0); 119 | colorTransferFunction->AddRGBPoint(216.0, 1.0, 0.0, 1.0); 120 | colorTransferFunction->AddRGBPoint(255.0, 1.0, 1.0, 1.0); 121 | 122 | // set up volume property 123 | auto volumeProperty = vtkSmartPointer::New(); 124 | volumeProperty->SetColor(colorTransferFunction); 125 | volumeProperty->SetScalarOpacity(opacityTransferFunction); 126 | volumeProperty->ShadeOff(); 127 | volumeProperty->SetInterpolationTypeToLinear(); 128 | 129 | // assign volume property to the volume property widget 130 | volumePropertywidget.setVolumeProperty(volumeProperty); 131 | 132 | // choose a volume mapper according to the checked menu item 133 | vtkSmartPointer volumeMapper; 134 | if (ui->action_vtkSlicerGPURayCastVolumeMapper->isChecked()) 135 | { 136 | volumeMapper = vtkSmartPointer::New(); 137 | } 138 | else 139 | { 140 | volumeMapper = vtkSmartPointer::New(); 141 | } 142 | volumeMapper->SetInputConnection(shiftScale->GetOutputPort()); 143 | 144 | // The volume holds the mapper and the property and can be used to position/orient the volume. 145 | auto volume = vtkSmartPointer::New(); 146 | volume->SetMapper(volumeMapper); 147 | volume->SetProperty(volumeProperty); 148 | 149 | // add the volume into the renderer 150 | auto renderer = vtkSmartPointer::New(); 151 | renderer->AddVolume(volume); 152 | renderer->SetBackground(1, 1, 1); 153 | 154 | // clean previous renderers and then add the current renderer 155 | auto window = widget.GetRenderWindow(); 156 | auto collection = window->GetRenderers(); 157 | auto item = collection->GetNextItem(); 158 | while (item != NULL) 159 | { 160 | window->RemoveRenderer(item); 161 | item = collection->GetNextItem(); 162 | } 163 | window->AddRenderer(renderer); 164 | window->Render(); 165 | 166 | // initialize the interactor 167 | interactor->Initialize(); 168 | interactor->Start(); 169 | } 170 | 171 | void VolumeRenderer::on_action_vtkSlicerGPURayCastVolumeMapper_triggered() 172 | { 173 | ui->action_vtkGPUVolumeRayCastMapper->setChecked(!ui->action_vtkSlicerGPURayCastVolumeMapper->isChecked()); 174 | } 175 | 176 | void VolumeRenderer::on_action_vtkGPUVolumeRayCastMapper_triggered() 177 | { 178 | ui->action_vtkSlicerGPURayCastVolumeMapper->setChecked(!ui->action_vtkGPUVolumeRayCastMapper->isChecked()); 179 | } 180 | 181 | void VolumeRenderer::on_actionScreenshotViewPane_triggered() 182 | { 183 | QString fileName = QFileDialog::getSaveFileName(this, "Save Screenshot", "", "Pircture Files (*.png *.jpg)"); 184 | 185 | if (fileName.isEmpty()) 186 | { 187 | return; 188 | } 189 | 190 | vtkSmartPointer windowToImageFilter = 191 | vtkSmartPointer::New(); 192 | windowToImageFilter->SetInput(this->widget.GetRenderWindow()); 193 | //windowToImageFilter->SetMagnification(3); 194 | windowToImageFilter->Update(); 195 | 196 | vtkSmartPointer writer = 197 | vtkSmartPointer::New(); 198 | writer->SetFileName(fileName.toStdString().c_str()); 199 | writer->SetInputConnection(windowToImageFilter->GetOutputPort()); 200 | writer->Write(); 201 | } -------------------------------------------------------------------------------- /VolumeRenderer.h: -------------------------------------------------------------------------------- 1 | #ifndef VOLUMERENDERER_H 2 | #define VOLUMERENDERER_H 3 | 4 | #include 5 | #include "ui_VolumeRenderer.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef VTK_OPENGL2 17 | #include 18 | #include 19 | #else 20 | #include 21 | #include 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "ctkTransferFunction.h" 43 | #include "ctkVTKColorTransferFunction.h" 44 | #include "ctkTransferFunctionView.h" 45 | #include "ctkTransferFunctionGradientItem.h" 46 | #include "ctkTransferFunctionControlPointsItem.h" 47 | #include "ctkVTKVolumePropertyWidget.h" 48 | 49 | #include "vtkSlicerGPURayCastVolumeMapper.h" 50 | 51 | namespace Ui{ 52 | class VolumeRenderer; 53 | } 54 | 55 | class VolumeRenderer : public QMainWindow 56 | { 57 | Q_OBJECT 58 | 59 | public: 60 | VolumeRenderer(QWidget *parent = 0, Qt::WFlags flags = 0); 61 | ~VolumeRenderer(); 62 | 63 | void SetInputImage(QString fileName); 64 | 65 | private: 66 | Ui::VolumeRenderer *ui; 67 | 68 | QString filename; 69 | vtkSmartPointer interactor; 70 | QVTKWidget widget; 71 | ctkVTKVolumePropertyWidget volumePropertywidget; 72 | 73 | private slots: 74 | void on_actionOpenImage_triggered(); 75 | void on_action_Exit_triggered(); 76 | void on_action_About_triggered(); 77 | void on_action_vtkSlicerGPURayCastVolumeMapper_triggered(); 78 | void on_action_vtkGPUVolumeRayCastMapper_triggered(); 79 | 80 | void on_actionScreenshotViewPane_triggered(); 81 | }; 82 | 83 | #endif // VOLUMERENDERER_H 84 | -------------------------------------------------------------------------------- /VolumeRenderer.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /VolumeRenderer.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | VolumeRenderer 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 700 11 | 12 | 13 | 14 | Volume Renderer 15 | 16 | 17 | 18 | 19 | 0 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 0 30 | 0 31 | 1000 32 | 26 33 | 34 | 35 | 36 | 37 | &File 38 | 39 | 40 | 41 | 42 | 43 | 44 | &Help 45 | 46 | 47 | 48 | 49 | 50 | Renderer 51 | 52 | 53 | 54 | 55 | 56 | 57 | Screenshot 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | TopToolBarArea 69 | 70 | 71 | false 72 | 73 | 74 | 75 | 76 | 77 | 2 78 | 79 | 80 | 81 | 82 | 0 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | &Open 93 | 94 | 95 | 96 | 97 | &Exit 98 | 99 | 100 | 101 | 102 | &About 103 | 104 | 105 | 106 | 107 | true 108 | 109 | 110 | vtkGPUVolumeRayCastMapper 111 | 112 | 113 | vtkGPUVolumeRayCastMapper 114 | 115 | 116 | 117 | 118 | true 119 | 120 | 121 | true 122 | 123 | 124 | vtkSlicerGPURayCastVolumeMapper 125 | 126 | 127 | 128 | 129 | ScreenshotViewPane 130 | 131 | 132 | 133 | 134 | OpenImage 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "MedicalImageTool.h" 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QApplication a(argc, argv); 12 | 13 | QPixmap pixmap("splashscreen.PNG"); 14 | QSplashScreen splash(pixmap); 15 | splash.show(); 16 | // QEventLoop eventloop; 17 | // QTimer::singleShot(100, &eventloop, SLOT(quit())); 18 | // eventloop.exec(); 19 | 20 | MedicalImageTool w; 21 | w.show(); 22 | return a.exec(); 23 | } 24 | --------------------------------------------------------------------------------