comparison Applications/Samples/Deprecated/BasicPetCtFusionApplication.h @ 1347:bfd77672d825 broker

Moved Application/Samples/* to Application/Samples/Deprecated/*
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 07 Apr 2020 14:29:01 +0200
parents Applications/Samples/BasicPetCtFusionApplication.h@8a0a62189f46
children
comparison
equal deleted inserted replaced
1346:df8bf351c23f 1347:bfd77672d825
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #pragma once
23
24 #include "SampleInteractor.h"
25
26 #include <Core/Logging.h>
27
28 namespace OrthancStone
29 {
30 namespace Samples
31 {
32 class BasicPetCtFusionApplication : public SampleApplicationBase
33 {
34 private:
35 class Interactor : public SampleInteractor
36 {
37 public:
38 static void SetStyle(LayeredSceneWidget& widget,
39 bool ct,
40 bool pet)
41 {
42 if (ct)
43 {
44 RenderStyle style;
45 style.windowing_ = ImageWindowing_Bone;
46 widget.SetLayerStyle(0, style);
47 }
48 else
49 {
50 RenderStyle style;
51 style.visible_ = false;
52 widget.SetLayerStyle(0, style);
53 }
54
55 if (ct && pet)
56 {
57 RenderStyle style;
58 style.applyLut_ = true;
59 style.alpha_ = 0.5;
60 widget.SetLayerStyle(1, style);
61 }
62 else if (pet)
63 {
64 RenderStyle style;
65 style.applyLut_ = true;
66 widget.SetLayerStyle(1, style);
67 }
68 else
69 {
70 RenderStyle style;
71 style.visible_ = false;
72 widget.SetLayerStyle(1, style);
73 }
74 }
75
76
77 static bool IsVisible(LayeredSceneWidget& widget,
78 size_t layer)
79 {
80 RenderStyle style = widget.GetLayerStyle(layer);
81 return style.visible_;
82 }
83
84
85 static void ToggleInterpolation(LayeredSceneWidget& widget,
86 size_t layer)
87 {
88 RenderStyle style = widget.GetLayerStyle(layer);
89
90 if (style.interpolation_ == ImageInterpolation_Bilinear)
91 {
92 style.interpolation_ = ImageInterpolation_Nearest;
93 }
94 else
95 {
96 style.interpolation_ = ImageInterpolation_Bilinear;
97 }
98
99 widget.SetLayerStyle(layer, style);
100 }
101
102
103 Interactor(VolumeImage& volume,
104 VolumeProjection projection,
105 bool reverse) :
106 SampleInteractor(volume, projection, reverse)
107 {
108 }
109
110
111 virtual void KeyPressed(WorldSceneWidget& widget,
112 char key,
113 KeyboardModifiers modifiers,
114 IStatusBar* statusBar)
115 {
116 LayeredSceneWidget& layered = dynamic_cast<LayeredSceneWidget&>(widget);
117
118 switch (key)
119 {
120 case 'c':
121 // Toggle the visibility of the CT layer
122 SetStyle(layered, !IsVisible(layered, 0), IsVisible(layered, 1));
123 break;
124
125 case 'p':
126 // Toggle the visibility of the PET layer
127 SetStyle(layered, IsVisible(layered, 0), !IsVisible(layered, 1));
128 break;
129
130 case 'i':
131 {
132 // Toggle on/off the interpolation
133 ToggleInterpolation(layered, 0);
134 ToggleInterpolation(layered, 1);
135 break;
136 }
137
138 default:
139 break;
140 }
141 }
142 };
143
144
145 public:
146 virtual void DeclareCommandLineOptions(boost::program_options::options_description& options)
147 {
148 boost::program_options::options_description generic("Sample options");
149 generic.add_options()
150 ("ct", boost::program_options::value<std::string>(),
151 "Orthanc ID of the CT series")
152 ("pet", boost::program_options::value<std::string>(),
153 "Orthanc ID of the PET series")
154 ("threads", boost::program_options::value<unsigned int>()->default_value(3),
155 "Number of download threads for the CT series")
156 ;
157
158 options.add(generic);
159 }
160
161 virtual void Initialize(BasicApplicationContext& context,
162 IStatusBar& statusBar,
163 const boost::program_options::variables_map& parameters)
164 {
165 using namespace OrthancStone;
166
167 if (parameters.count("ct") != 1 ||
168 parameters.count("pet") != 1)
169 {
170 LOG(ERROR) << "The series ID is missing";
171 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
172 }
173
174 std::string ct = parameters["ct"].as<std::string>();
175 std::string pet = parameters["pet"].as<std::string>();
176 unsigned int threads = parameters["threads"].as<unsigned int>();
177
178 VolumeImage& ctVolume = context.AddSeriesVolume(ct, true /* progressive download */, threads);
179 VolumeImage& petVolume = context.AddSeriesVolume(pet, true /* progressive download */, 1);
180
181 // Take the PET volume as the reference for the slices
182 std::unique_ptr<Interactor> interactor(new Interactor(petVolume, VolumeProjection_Axial, false /* don't reverse normal */));
183
184 std::unique_ptr<LayeredSceneWidget> widget(new LayeredSceneWidget);
185 widget->AddLayer(new VolumeImage::LayerFactory(ctVolume));
186 widget->AddLayer(new VolumeImage::LayerFactory(petVolume));
187 widget->SetSlice(interactor->GetCursor().GetCurrentSlice());
188 widget->SetInteractor(*interactor);
189
190 Interactor::SetStyle(*widget, true, true); // Initially, show both CT and PET layers
191
192 context.AddInteractor(interactor.release());
193 context.SetCentralWidget(widget.release());
194
195 statusBar.SetMessage("Use the key \"t\" to toggle the fullscreen mode");
196 statusBar.SetMessage("Use the key \"c\" to show/hide the CT layer");
197 statusBar.SetMessage("Use the key \"p\" to show/hide the PET layer");
198 statusBar.SetMessage("Use the key \"i\" to toggle the smoothing of the images");
199 }
200 };
201 }
202 }