DGtalTools  1.2.0
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/Viewer3D.h"
37 #include "DGtal/io/DrawWithDisplay3DModifier.h"
38 #include "DGtal/io/readers/PointListReader.h"
39 #include "DGtal/io/readers/MeshReader.h"
40 #include "DGtal/topology/helpers/Surfaces.h"
41 #include "DGtal/topology/SurfelAdjacency.h"
42 
43 #include "DGtal/io/Color.h"
44 #include "DGtal/io/colormaps/GradientColorMap.h"
45 #include "DGtal/io/readers/GenericReader.h"
46 #ifdef WITH_ITK
47 #include "DGtal/io/readers/DicomReader.h"
48 #endif
49 
50 #include "DGtal/images/ImageSelector.h"
51 
52 
53 
54 #include "specificClasses/Viewer3DImage.cpp"
55 
56 #include "CLI11.hpp"
57 
58 
59 
60 using namespace std;
61 using namespace DGtal;
62 using namespace Z3i;
63 
64 
122 int 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 QGLviewer\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 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", true);
166  app.add_option("--thresholdMax", thresholdMax, "threshold maw to define binary shape", true);
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).", true);
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", true );
182  app.add_option("--scaleY,-y", sy, "set the scale value in the Y direction", true );
183  app.add_option("--scaleZ,-z", sy, "set the scale value in the Z direction", true );
184  app.add_option("--rescaleInputMin",rescaleInputMin, "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true );
185  app.add_option("--rescaleInputMax",rescaleInputMax, "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true );
186  app.add_option("--transparency,-t",transp, "change the default transparency", true );
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  QApplication application(argc,argv);
195 
196 
197  string extension = inputFileName.substr(inputFileName.find_last_of(".") + 1);
198 
200  if(emptyMode)
202  else if(grid)
204  else if(intergrid)
206  else
208 
209  Viewer3DImage<> viewer(mode);
210  viewer.setWindowTitle("simple Volume Viewer");
211  viewer.show();
212  viewer.setGLScale(sx, sy, sz);
213 
214  typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
215  Image3D image = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
216  rescaleInputMax,
217  0, 255) );
218  Domain domain = image.domain();
219 
220  trace.info() << "Image loaded: "<<image<< std::endl;
221  viewer.setVolImage(&image);
222 
223  // Used to display 3D surface
224  Z3i::DigitalSet set3d(domain);
225 
226  viewer << Viewer3D<>::updateDisplay;
227  if(thresholdImage){
228  GradientColorMap<long> gradient( thresholdMin, thresholdMax);
229  gradient.addColor(Color::Blue);
230  gradient.addColor(Color::Green);
231  gradient.addColor(Color::Yellow);
232  gradient.addColor(Color::Red);
233  for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
234  unsigned char val= image( (*it) );
235  Color c= gradient(val);
236  if(val<=thresholdMax && val >=thresholdMin)
237  {
238  if(!displayDigitalSurface)
239  {
240  viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp),
241  Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp));
242  viewer << *it;
243  }
244  }else
245  {
246  set3d.insert(*it);
247  }
248  }
249  }
250 
251  if(inputFileNameSDP != "" ){
252  if(colorSDP.size()==4){
253  Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
254  viewer << CustomColors3D(c, c);
255  }
256 
257  vector<Z3i::Point> vectVoxels;
258  if(vectSDPIndex.size()==3)
259  {
260  vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP, vectSDPIndex);
261  }else
262  {
263  vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(inputFileNameSDP);
264  }
265  for(unsigned int i=0;i< vectVoxels.size(); i++)
266  {
267  if(!displayDigitalSurface)
268  {
269  if(ballRadius != 0.0)
270  {
271  viewer.addBall (vectVoxels.at(i), ballRadius);
272  }
273  else
274  {
275  viewer << vectVoxels.at(i);
276  }
277  }
278  else
279  {
280  set3d.insert(vectVoxels.at(i));
281  }
282  }
283  }
284 
285  if(inputFileNameMesh != "")
286  {
287  if(colorMesh.size() != 0)
288  {
289  Color c(colorMesh[0], colorMesh[1], colorMesh[2], colorMesh[3]);
290  viewer.setFillColor(c);
291  }
292  DGtal::Mesh<Z3i::RealPoint> aMesh(colorMesh.size() == 0);
293  MeshReader<Z3i::RealPoint>::importOFFFile(inputFileNameMesh, aMesh);
294  viewer << aMesh;
295  }
296 
297  if(displayDigitalSurface)
298  {
299  KSpace K;
300  Point low = domain.lowerBound(); low[0]=low[0]-1; low[1]=low[1]-1; low[2]=low[2]-1;
301  Point upp = domain.upperBound(); upp[0]=upp[0]+1; upp[1]=upp[1]+1; upp[2]=upp[2]+1;
302  K.init(low, upp , true);
303  SurfelAdjacency<3> SAdj( true );
304  vector<vector<SCell> > vectConnectedSCell;
305  trace.info() << "Extracting surface set ... " ;
306  Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, set3d, true);
307  trace.info()<< " [done] " <<std::endl;
308  GradientColorMap<long> gradient( 0, vectConnectedSCell.size());
309  gradient.addColor(DGtal::Color::Red);
310  gradient.addColor(DGtal::Color::Yellow);
311  gradient.addColor(DGtal::Color::Green);
312  gradient.addColor(DGtal::Color::Cyan);
313  gradient.addColor(DGtal::Color::Blue);
314  gradient.addColor(DGtal::Color::Magenta);
315  gradient.addColor(DGtal::Color::Red);
316 
317  viewer << DGtal::SetMode3D(vectConnectedSCell.at(0).at(0).className(), "Basic");
318  for(unsigned int i= 0; i <vectConnectedSCell.size(); i++)
319  {
320  for(unsigned int j= 0; j <vectConnectedSCell.at(i).size(); j++)
321  {
322  if(colorizeCC)
323  {
324  DGtal::Color c= gradient(i);
325  viewer << CustomColors3D(Color(250, 0,0, transp), Color(c.red(),
326  c.green(),
327  c.blue(), transp));
328  }else if(colorSDP.size() != 0)
329  {
330  Color c(colorSDP[0], colorSDP[1], colorSDP[2], colorSDP[3]);
331  viewer << CustomColors3D(c, c);
332  }
333  viewer << vectConnectedSCell.at(i).at(j);
334  }
335  }
336  }
337 
338  viewer << Viewer3D<>::updateDisplay;
339  DGtal::Z3i::Point size = image.domain().upperBound() - image.domain().lowerBound();
340  DGtal::Z3i::Point center = image.domain().lowerBound()+size/2;
341  unsigned int maxDist = std::max(std::max(size[2], size[1]), size[0]);
342  viewer.camera()->setPosition(qglviewer::Vec(center[0],center[1],
343  center[2] + 2.0*maxDist));
344  viewer.camera()->setSceneCenter(qglviewer::Vec(center[0],center[1],center[2]));
345  return application.exec();
346 }
Definition: ATu0v1.h:57