DGtalTools  1.5.beta
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 
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 
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 }
int main(int argc, char **argv)
static const Color Yellow
static const Color Cyan
void green(const unsigned char aGreenValue)
static const Color Green
void red(const unsigned char aRedValue)
static const Color Red
static const Color Blue
void blue(const unsigned char aBlueValue)
static const Color Magenta
const Domain & domain() const
typename Self::Domain Domain
typename Self::Point Point
bool init(const Point &lower, const Point &upper, bool isClosed)
const Point & lowerBound() const
std::ostream & info()
boost::int64_t int64_t
Trace trace(traceWriterTerm)