DGtalTools  0.9.2
3dImageViewer.cpp
1 
29 #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 <boost/program_options/options_description.hpp>
57 #include <boost/program_options/parsers.hpp>
58 #include <boost/program_options/variables_map.hpp>
59 
60 
61 using namespace std;
62 using namespace DGtal;
63 using namespace Z3i;
64 
65 
129 namespace po = boost::program_options;
131 
132 int main( int argc, char** argv )
133 {
134 
135  typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D;
136  typedef DGtal::ImageContainerBySTLVector<DGtal::Z2i::Domain, unsigned char > Image2D;
137 
138 
139  // parse command line ----------------------------------------------
140  po::options_description general_opt("Allowed options are ");
141  general_opt.add_options()
142  ("help,h", "display this message")
143  ("input,i", po::value<std::string>(), "vol file (.vol) , pgm3d (.p3d or .pgm3d) file or sdp (sequence of discrete points)" )
144  ("grid", "draw slice images using grid mode. " )
145  ("intergrid", "draw slice images using inter grid mode. " )
146  ("emptyMode", "remove the default boundingbox display " )
147  ("thresholdImage", "threshold the image to define binary shape" )
148  ("thresholdMin,m", po::value<int>()->default_value(0), "threshold min to define binary shape" )
149  ("thresholdMax,M", po::value<int>()->default_value(255), "threshold max to define binary shape" )
150  ("displaySDP,s", po::value<std::string>(), "display a set of discrete points (.sdp)" )
151  ("SDPindex", po::value<std::vector <unsigned int> >()->multitoken(), "specify the sdp index (by default 0,1,2).")
152  ("SDPball", po::value<double>()->default_value(0.5), "use balls to display a set of discrete points (used with displaySDP option)")
153  ("displayMesh", po::value<std::string>(), "display a Mesh given in OFF or OFS format. " )
154  ("displayDigitalSurface", "display the digital surface instead of display all the set of voxels (used with thresholdImage or displaySDP options)" )
155  ("colorizeCC", "colorize each Connected Components of the surface displayed by displayDigitalSurface option." )
156  ("colorSDP,c", po::value<std::vector <int> >()->multitoken(), "set the color discrete points: r g b a " )
157  ("colorMesh", po::value<std::vector <int> >()->multitoken(), "set the color of Mesh (given from displayMesh option) : r g b a " )
158  ("scaleX,x", po::value<float>()->default_value(1.0), "set the scale value in the X direction (default 1.0)" )
159  ("scaleY,y", po::value<float>()->default_value(1.0), "set the scale value in the Y direction (default 1.0)" )
160  ("scaleZ,z", po::value<float>()->default_value(1.0), "set the scale value in the Z direction (default 1.0)")
161 #ifdef WITH_ITK
162  ("dicomMin", po::value<int>()->default_value(-1000), "set minimum density threshold on Hounsfield scale")
163  ("dicomMax", po::value<int>()->default_value(3000), "set maximum density threshold on Hounsfield scale")
164 #endif
165  ("transparency,t", po::value<uint>()->default_value(255), "transparency") ;
166 
167  bool parseOK=true;
168  po::variables_map vm;
169  try{
170  po::store(po::parse_command_line(argc, argv, general_opt), vm);
171  }catch(const std::exception& ex){
172  parseOK=false;
173  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
174  }
175  po::notify(vm);
176  if( !parseOK || vm.count("help")||argc<=1)
177  {
178  std::cout << "Usage: " << argv[0] << " [input]\n"
179  << "Displays volume file as a voxel set by using QGLviewer"
180  << general_opt << "\n";
181  return 0;
182  }
183 
184  if(! vm.count("input"))
185  {
186  trace.error() << " The file name was defined" << endl;
187  return 0;
188  }
189  string inputFilename = vm["input"].as<std::string>();
190  int thresholdMin = vm["thresholdMin"].as<int>();
191  int thresholdMax = vm["thresholdMax"].as<int>();
192  unsigned char transp = vm["transparency"].as<uint>();
193 
194  QApplication application(argc,argv);
195 
196  float sx = vm["scaleX"].as<float>();
197  float sy = vm["scaleY"].as<float>();
198  float sz = vm["scaleZ"].as<float>();
199 
200  double ballRadius = vm["SDPball"].as<double>();
201  string extension = inputFilename.substr(inputFilename.find_last_of(".") + 1);
202  if(extension!="vol" && extension != "p3d" && extension != "pgm3D" && extension != "pgm3d" && extension != "sdp" && extension != "pgm"
203 #ifdef WITH_ITK
204  && extension !="dcm"
205 #endif
206  ){
207  trace.info() << "File extension not recognized: "<< extension << std::endl;
208  return 0;
209  }
211  if(vm.count("emptyMode"))
213  else if(vm.count("grid"))
215  else if(vm.count("intergrid"))
217  else
219 
220  Viewer3DImage<> viewer(mode);
221  viewer.setWindowTitle("simple Volume Viewer");
222  viewer.show();
223  viewer.setGLScale(sx, sy, sz);
224 
225 #ifdef WITH_ITK
226  int dicomMin = vm["dicomMin"].as<int>();
227  int dicomMax = vm["dicomMax"].as<int>();
228  typedef DGtal::functors::Rescaling<int ,unsigned char > RescalFCT;
229 
230  Image3D image = extension == "dcm" ? DicomReader< Image3D, RescalFCT >::importDicom( inputFilename,
231  RescalFCT(dicomMin,
232  dicomMax,
233  0, 255) ) :
234  GenericReader<Image3D>::import( inputFilename );
235 #else
236  Image3D image = GenericReader<Image3D>::import( inputFilename );
237 #endif
238  Domain domain = image.domain();
239 
240  trace.info() << "Image loaded: "<<image<< std::endl;
241  viewer.setVolImage(&image);
242  viewer << Z3i::Point(512, 512, 0);
243  // Used to display 3D surface
244  Z3i::DigitalSet set3d(domain);
245 
246 
247 
248  viewer << Viewer3D<>::updateDisplay;
249  if(vm.count("thresholdImage")){
250  GradientColorMap<long> gradient( thresholdMin, thresholdMax);
251  gradient.addColor(Color::Blue);
252  gradient.addColor(Color::Green);
253  gradient.addColor(Color::Yellow);
254  gradient.addColor(Color::Red);
255  for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
256  unsigned char val= image( (*it) );
257  Color c= gradient(val);
258  if(val<=thresholdMax && val >=thresholdMin){
259  if(!vm.count("displayDigitalSurface")){
260  viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp),
261  Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp));
262  viewer << *it;
263  }
264  }else{
265  set3d.insert(*it);
266  }
267  }
268  }
269 
270  if(vm.count("displaySDP")){
271  if(vm.count("colorSDP")){
272  std::vector<int> vcol= vm["colorSDP"].as<std::vector<int > >();
273  if(vcol.size()<4){
274  trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl;
275  return 0;
276  }
277  Color c(vcol[0], vcol[1], vcol[2], vcol[3]);
278  viewer << CustomColors3D(c, c);
279  }
280 
281  vector<Z3i::Point> vectVoxels;
282  if(vm.count("SDPindex")) {
283  std::vector<unsigned int > vectIndex = vm["SDPindex"].as<std::vector<unsigned int > >();
284  if(vectIndex.size()!=3){
285  trace.error() << "you need to specify the three indexes of vertex." << std::endl;
286  return 0;
287  }
288  vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(vm["displaySDP"].as<std::string>(), vectIndex);
289  }else{
290  vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(vm["displaySDP"].as<std::string>());
291  }
292  for(unsigned int i=0;i< vectVoxels.size(); i++){
293  if(!vm.count("displayDigitalSurface")){
294  if(vm.count("SDPball")){
295  viewer.addBall (vectVoxels.at(i), ballRadius);
296  }else{
297  viewer << vectVoxels.at(i);
298  }
299  }else{
300  set3d.insert(vectVoxels.at(i));
301  }
302  }
303  }
304 
305  if(vm.count("displayMesh")){
306  if(vm.count("colorMesh")){
307  std::vector<int> vcol= vm["colorMesh"].as<std::vector<int > >();
308  if(vcol.size()<4){
309  trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl;
310  return 0;
311  }
312  Color c(vcol[0], vcol[1], vcol[2], vcol[3]);
313  viewer.setFillColor(c);
314  }
315 
316  DGtal::Mesh<Z3i::RealPoint> aMesh(!vm.count("colorMesh"));
317  MeshReader<Z3i::RealPoint>::importOFFFile(vm["displayMesh"].as<std::string>(), aMesh);
318  viewer << aMesh;
319  }
320 
321  if(vm.count("displayDigitalSurface")){
322  KSpace K;
323  Point low = domain.lowerBound(); low[0]=low[0]-1; low[1]=low[1]-1; low[2]=low[2]-1;
324  Point upp = domain.upperBound(); upp[0]=upp[0]+1; upp[1]=upp[1]+1; upp[2]=upp[2]+1;
325  K.init(low, upp , true);
326  SurfelAdjacency<3> SAdj( true );
327  vector<vector<SCell> > vectConnectedSCell;
328  trace.info() << "Extracting surface set ... " ;
329  Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, set3d, true);
330  trace.info()<< " [done] " <<std::endl;
331  GradientColorMap<long> gradient( 0, vectConnectedSCell.size());
332  gradient.addColor(DGtal::Color::Red);
333  gradient.addColor(DGtal::Color::Yellow);
334  gradient.addColor(DGtal::Color::Green);
335  gradient.addColor(DGtal::Color::Cyan);
336  gradient.addColor(DGtal::Color::Blue);
337  gradient.addColor(DGtal::Color::Magenta);
338  gradient.addColor(DGtal::Color::Red);
339 
340  viewer << DGtal::SetMode3D(vectConnectedSCell.at(0).at(0).className(), "Basic");
341  for(unsigned int i= 0; i <vectConnectedSCell.size(); i++){
342  for(unsigned int j= 0; j <vectConnectedSCell.at(i).size(); j++){
343  if(vm.count("colorizeCC")){
344  DGtal::Color c= gradient(i);
345  viewer << CustomColors3D(Color(250, 0,0, transp), Color(c.red(),
346  c.green(),
347  c.blue(), transp));
348  }else if(vm.count("colorSDP")){
349  std::vector<int> vcol= vm["colorSDP"].as<std::vector<int > >();
350  Color c(vcol[0], vcol[1], vcol[2], vcol[3]);
351  viewer << CustomColors3D(c, c);
352  }
353 
354  viewer << vectConnectedSCell.at(i).at(j);
355  }
356  }
357  }
358 
359  viewer << Viewer3D<>::updateDisplay;
360  return application.exec();
361 }
STL namespace.