├── CTK
├── README
└── CTK.rar
├── Slicer
├── README
└── Slicer.rar
├── Resources
├── README
├── 1.png
├── 2.png
├── 3.jpg
├── 4.png
├── 5.png
├── 6.png
├── 7.png
├── 8.jpg
├── 9.png
├── exit.png
├── fileopen.png
├── filesave.png
└── splashscreen.PNG
├── Result
├── README
├── pic1.png
├── pic2.png
└── pic3.png
├── Medical Image Data
├── ReadMe
├── heart.raw
├── nucleon.raw
├── nucleon.mhd
└── heart.mhd
├── ImageToSTL.qrc
├── VolumeRenderer.qrc
├── STLSet.qrc
├── DistanceMeasurement.qrc
├── About.qrc
├── Crosshair.qrc
├── MedicalImageTool.qrc
├── STLSet.cpp
├── STLSet.h
├── About.cpp
├── DistanceMeasurement.cpp
├── About.h
├── Crosshair.cpp
├── Crosshair.h
├── main.cpp
├── DistanceMeasurement.h
├── README.md
├── VolumeRenderer.h
├── DistanceMeasurement.ui
├── About.ui
├── STLSet.ui
├── MedicalImageTool.h
├── ImageToSTL.h
├── Crosshair.ui
├── VolumeRenderer.ui
├── CMakeLists.txt
├── MedicalImageTool.ui
├── VolumeRenderer.cpp
├── MedicalImageTool.cpp
├── ImageToSTL.cpp
└── ImageToSTL.ui
/CTK/README:
--------------------------------------------------------------------------------
1 | Volume renderer of CTK
2 |
--------------------------------------------------------------------------------
/Slicer/README:
--------------------------------------------------------------------------------
1 | Volume renderer of Slicer
2 |
--------------------------------------------------------------------------------
/Resources/README:
--------------------------------------------------------------------------------
1 | Qt's project resource file
2 |
--------------------------------------------------------------------------------
/Result/README:
--------------------------------------------------------------------------------
1 | The program running results
2 |
--------------------------------------------------------------------------------
/Medical Image Data/ReadMe:
--------------------------------------------------------------------------------
1 | heart and nucleon image file
2 |
--------------------------------------------------------------------------------
/CTK/CTK.rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/CTK/CTK.rar
--------------------------------------------------------------------------------
/Resources/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/1.png
--------------------------------------------------------------------------------
/Resources/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/2.png
--------------------------------------------------------------------------------
/Resources/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/3.jpg
--------------------------------------------------------------------------------
/Resources/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/4.png
--------------------------------------------------------------------------------
/Resources/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/5.png
--------------------------------------------------------------------------------
/Resources/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/6.png
--------------------------------------------------------------------------------
/Resources/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/7.png
--------------------------------------------------------------------------------
/Resources/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/8.jpg
--------------------------------------------------------------------------------
/Resources/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/9.png
--------------------------------------------------------------------------------
/Result/pic1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Result/pic1.png
--------------------------------------------------------------------------------
/Result/pic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Result/pic2.png
--------------------------------------------------------------------------------
/Result/pic3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Result/pic3.png
--------------------------------------------------------------------------------
/Slicer/Slicer.rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Slicer/Slicer.rar
--------------------------------------------------------------------------------
/ImageToSTL.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Resources/exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/exit.png
--------------------------------------------------------------------------------
/Resources/fileopen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/fileopen.png
--------------------------------------------------------------------------------
/Resources/filesave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/filesave.png
--------------------------------------------------------------------------------
/VolumeRenderer.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Resources/splashscreen.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Resources/splashscreen.PNG
--------------------------------------------------------------------------------
/Medical Image Data/heart.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Medical Image Data/heart.raw
--------------------------------------------------------------------------------
/STLSet.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/9.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Medical Image Data/nucleon.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangdemon/Medical-Image-Tool/HEAD/Medical Image Data/nucleon.raw
--------------------------------------------------------------------------------
/DistanceMeasurement.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/8.jpg
4 |
5 |
6 |
--------------------------------------------------------------------------------
/About.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/3.jpg
4 | Resources/4.png
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Crosshair.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/2.png
4 | Resources/6.png
5 | Resources/7.png
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/MedicalImageTool.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources/exit.png
4 | Resources/fileopen.png
5 | Resources/filesave.png
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | 
19 | # Result 2
20 | 
21 | # Result 3
22 | 
23 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
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 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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 |
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 |
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 |
--------------------------------------------------------------------------------