DGtalTools 2.0.0
Loading...
Searching...
No Matches
3dImageViewer.cpp
1
30#include <iostream>
31
32#include "DGtal/base/Common.h"
33#include "DGtal/base/BasicFunctors.h"
34#include "DGtal/helpers/StdDefs.h"
35#include "DGtal/io/readers/VolReader.h"
36#include "DGtal/io/viewers/PolyscopeViewer.h"
37#include "DGtal/io/readers/PointListReader.h"
38#include "DGtal/io/readers/MeshReader.h"
39#include "DGtal/topology/helpers/Surfaces.h"
40#include "DGtal/topology/SurfelAdjacency.h"
41
42#include "DGtal/io/Color.h"
43#include "DGtal/io/colormaps/GradientColorMap.h"
44#include "DGtal/io/readers/GenericReader.h"
45#ifdef DGTAL_WITH_ITK
46#include "DGtal/io/readers/DicomReader.h"
47#endif
48
49#include "DGtal/images/ImageSelector.h"
50
51
52
53// #include "specificClasses/Viewer3DImage.cpp"
54
55#include "CLI11.hpp"
56
57
58
59using namespace std;
60using namespace DGtal;
61using namespace Z3i;
62
63
122int main( int argc, char** argv )
123{
124
125 typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D;
126 typedef DGtal::ImageContainerBySTLVector<DGtal::Z2i::Domain, unsigned char > Image2D;
127
128 // parse command line using CLI ----------------------------------------------
129 CLI::App app;
130 std::string inputFileName;
131 std::string inputFileNameSDP;
132 std::string inputFileNameMesh;
133
134 DGtal::int64_t rescaleInputMin {0};
135 DGtal::int64_t rescaleInputMax {255};
136 bool grid {false};
137 bool intergrid {false};
138 bool emptyMode {false};
139 bool displayDigitalSurface {false};
140 bool thresholdImage {false};
141 bool colorizeCC {false};
142 int thresholdMin {0};
143 int thresholdMax {255};
144 std::vector<unsigned int> vectSDPIndex {0,1,2};
145 std::vector<unsigned int> colorSDP;
146 std::vector<unsigned int> colorMesh;
147
148 float sx {1.0};
149 float sy {1.0};
150 float sz {1.0};
151 double ballRadius = {0.0};
152 unsigned char transp {255};
153
154
155 app.description("Displays volume file as a voxel set by using PolyscopeViewer\n 3dImageViewer $DGtal/examples/samples/lobster.vol --thresholdImage -m 180");
156
157 app.add_option("-i,--input,1", inputFileName, "vol file (.vol, .longvol .p3d, .pgm3d and if DGTAL_WITH_ITK is selected: dicom, dcm, mha, mhd). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." )
158 ->required()
159 ->check(CLI::ExistingFile);
160
161 app.add_flag("--grid", grid , "draw slice images using grid mode.");
162 app.add_flag("--intergrid", grid , "draw slice images using inter grid mode.");
163 app.add_flag("--emptyMode", emptyMode,"remove the default boundingbox display.");
164 app.add_flag("--thresholdImage", thresholdImage,"threshold the image to define binary shape");
165 app.add_option("--thresholdMin", thresholdMin, "threshold min to define binary shape");
166 app.add_option("--thresholdMax", thresholdMax, "threshold maw to define binary shape");
167 app.add_option("--displaySDP,s",inputFileNameSDP, "display a set of discrete points (.sdp)" );
168 app.add_option("--SDPindex", vectSDPIndex, "specify the sdp index.")
169 ->expected(3);
170 app.add_option("--SDPball",ballRadius, "use balls to display a set of discrete points (if not set to 0 and used with displaySDP option).");
171
172 app.add_option("--displayMesh", inputFileNameMesh, "display a Mesh given in OFF or OFS format.");
173 app.add_flag("--displayDigitalSurface",displayDigitalSurface, "display the digital surface instead of display all the set of voxels (used with thresholdImage or displaySDP options)" );
174
175 app.add_flag("--colorizeCC", colorizeCC, "colorize each Connected Components of the surface displayed by displayDigitalSurface option.");
176 app.add_option("--colorSDP,-c", colorSDP, "set the color discrete points: r g b a ")
177 ->expected(4);
178 app.add_option("--colorMesh", colorMesh, "set the color of Mesh (given from displayMesh option) : r g b a ")
179 ->expected(4);
180
181 app.add_option("--scaleX,-x", sx, "set the scale value in the X direction" );
182 app.add_option("--scaleY,-y", sy, "set the scale value in the Y direction" );
183 app.add_option("--scaleZ,-z", sy, "set the scale value in the Z direction" );
184 app.add_option("--rescaleInputMin",rescaleInputMin, "min value used to rescale the input intensity (to avoid basic cast into 8 bits image)." );
185 app.add_option("--rescaleInputMax",rescaleInputMax, "max value used to rescale the input intensity (to avoid basic cast into 8 bits image)." );
186 app.add_option("--transparency,-t",transp, "change the default transparency" );
187
188
189 app.get_formatter()->column_width(40);
190 CLI11_PARSE(app, argc, argv);
191 // END parse command line using CLI ----------------------------------------------
192
193
194 string extension = inputFileName.substr(inputFileName.find_last_of(".") + 1);
195
196 PolyscopeViewer<> viewer;
197
198 typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
199 Image3D image = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
200 rescaleInputMax,
201 0,
202 255));
203 Domain domain = image.domain();
204
205 trace.info() << "Image loaded: "<<image<< std::endl;
206 viewer << image;
207
208 // Used to display 3D surface
209 Z3i::DigitalSet set3d(domain);
210
211 if(thresholdImage){
212 viewer.newCubeList("Threshold image");
213 viewer.allowReuseList = true;
214 for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
215 unsigned char val= image( (*it) );
216 if(val<=thresholdMax && val >=thresholdMin)
217 {
218 if(!displayDigitalSurface)
219 {
220 viewer << WithQuantity(*it, "value", val);
221 }
222 }else
223 {
224 set3d.insert(*it);
225 }
226 }
227 viewer.endCurrentGroup();
228 }
229
230 if(inputFileNameSDP != "" ){
231 if(colorSDP.size()==4){
232 Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
233 viewer << c;
234 }
235
236 vector<Z3i::Point> vectVoxels;
237 if(vectSDPIndex.size()==3)
238 {
239 vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP, vectSDPIndex);
240 }else
241 {
242 vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP);
243 }
244
245 if (ballRadius != 0.0) viewer.drawAsBalls();
246 for(unsigned int i=0;i< vectVoxels.size(); i++)
247 {
248 if(!displayDigitalSurface)
249 {
250 viewer << vectVoxels.at(i);
251 }
252 else
253 {
254 set3d.insert(vectVoxels.at(i));
255 }
256 }
257 viewer.drawAsPaving();
258 }
259
260 if(inputFileNameMesh != "")
261 {
262 if(colorMesh.size() != 0)
263 {
264 Color c(colorMesh[0], colorMesh[1], colorMesh[2], colorMesh[3]);
265 viewer.drawColor(c);
266 }
267 DGtal::Mesh<Z3i::RealPoint> aMesh(colorMesh.size() == 0);
268 MeshReader<Z3i::RealPoint>::importOFFFile(inputFileNameMesh, aMesh);
269 viewer << aMesh;
270 }
271
272 if(displayDigitalSurface)
273 {
274 KSpace K;
275 Point low = domain.lowerBound(); low[0]=low[0]-1; low[1]=low[1]-1; low[2]=low[2]-1;
276 Point upp = domain.upperBound(); upp[0]=upp[0]+1; upp[1]=upp[1]+1; upp[2]=upp[2]+1;
277 K.init(low, upp , true);
278 SurfelAdjacency<3> SAdj( true );
279 vector<vector<SCell> > vectConnectedSCell;
280 trace.info() << "Extracting surface set ... " ;
281 Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, set3d, true);
282 trace.info()<< " [done] " <<std::endl;
283
284 viewer.drawAsSimplified();
285 for(unsigned int i= 0; i <vectConnectedSCell.size(); i++)
286 {
287 for(unsigned int j= 0; j <vectConnectedSCell.at(i).size(); j++)
288 {
289 const auto& toDraw = vectConnectedSCell.at(i).at(j);
290 if(colorizeCC)
291 {
292 viewer << WithQuantity(toDraw, "index", i);
293 }
294 else if(colorSDP.size() != 0)
295 {
296 Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
297 viewer << WithQuantity(toDraw, "color", c);
298 }
299 else
300 {
301 viewer << toDraw;
302 }
303 }
304 }
305 }
306
307 DGtal::Z3i::Point size = image.domain().upperBound() - image.domain().lowerBound();
308 DGtal::Z3i::Point center = image.domain().lowerBound()+size/2;
309 unsigned int maxDist = std::max(std::max(size[2], size[1]), size[0]);
310 viewer.show();
311 return 0;
312}
Definition ATu0v1.h:57