DGtalTools  0.9.3
3dVolViewer.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/GenericReader.h"
36 #ifdef WITH_ITK
37 #include "DGtal/io/readers/DicomReader.h"
38 #endif
39 #include "DGtal/io/viewers/Viewer3D.h"
40 #include "DGtal/io/DrawWithDisplay3DModifier.h"
41 #include "DGtal/io/readers/PointListReader.h"
42 #include "DGtal/io/readers/MeshReader.h"
43 
44 #include "DGtal/io/Color.h"
45 #include "DGtal/io/colormaps/GradientColorMap.h"
46 #include "DGtal/images/ImageSelector.h"
47 
48 #include <boost/program_options/options_description.hpp>
49 #include <boost/program_options/parsers.hpp>
50 #include <boost/program_options/variables_map.hpp>
51 
52 using namespace std;
53 using namespace DGtal;
54 using namespace Z3i;
55 
56 
110 template < typename Space = DGtal::Z3i::Space, typename KSpace = DGtal::Z3i::KSpace>
111 struct ViewerSnap: DGtal::Viewer3D <Space, KSpace>
112 {
113 
114  ViewerSnap(bool saveSnap): Viewer3D<Space, KSpace>(), mySaveSnap(saveSnap){
115  };
116 
117  virtual void
118  init(){
119  DGtal::Viewer3D<>::init();
120  if(mySaveSnap){
121  QObject::connect(this, SIGNAL(drawFinished(bool)), this, SLOT(saveSnapshot(bool)));
122  }
123  };
124  bool mySaveSnap;
125 };
126 
127 
129 namespace po = boost::program_options;
130 
131 int main( int argc, char** argv )
132 {
133  // parse command line ----------------------------------------------
134  po::options_description general_opt("Allowed options are: ");
135  general_opt.add_options()
136  ("help,h", "display this message")
137  ("input,i", po::value<std::string>(), "vol file (.vol) , pgm3d (.p3d or .pgm3d, pgm (with 3 dims)) file or sdp (sequence of discrete points)" )
138  ("thresholdMin,m", po::value<int>()->default_value(0), "threshold min to define binary shape" )
139  ("thresholdMax,M", po::value<int>()->default_value(255), "threshold max to define binary shape" )
140  ("numMaxVoxel,n", po::value<int>()->default_value(500000), "set the maximal voxel number to be displayed." )
141  ("displayMesh", po::value<std::string>(), "display a Mesh given in OFF or OFS format. " )
142  ("colorMesh", po::value<std::vector <int> >()->multitoken(), "set the color of Mesh (given from displayMesh option) : r g b a " )
143  ("doSnapShotAndExit,d", po::value<std::string>(), "save display snapshot into file. Notes that the camera setting is set by default according the last saved configuration (use SHIFT+Key_M to save current camera setting in the Viewer3D). If the camera setting was not saved it will use the default camera setting." )
144 #ifdef WITH_ITK
145  ("dicomMin", po::value<int>()->default_value(-1000), "set minimum density threshold on Hounsfield scale")
146  ("dicomMax", po::value<int>()->default_value(3000), "set maximum density threshold on Hounsfield scale")
147 #endif
148  ("transparency,t", po::value<uint>()->default_value(255), "transparency") ;
149 
150  bool parseOK=true;
151  po::variables_map vm;
152  try{
153  po::store(po::parse_command_line(argc, argv, general_opt), vm);
154  }catch(const std::exception& ex){
155  parseOK=false;
156  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
157  }
158  po::notify(vm);
159  if( !parseOK || vm.count("help")||argc<=1)
160  {
161  std::cout << "Usage: " << argv[0] << " [input]\n"
162  << "Display volume file as a voxel set by using QGLviewer"<< endl
163  << general_opt << "\n"
164  << "Example: "<< std::endl
165  << " \t 3dVolViewer -i $DGtal/examples/samples/lobster.vol -m 60 -t 10" << endl;
166  return 0;
167  }
168 
169  if(! vm.count("input"))
170  {
171  trace.error() << " The file name was defined" << endl;
172  return 0;
173  }
174  string inputFilename = vm["input"].as<std::string>();
175  int thresholdMin = vm["thresholdMin"].as<int>();
176  int thresholdMax = vm["thresholdMax"].as<int>();
177  unsigned char transp = vm["transparency"].as<uint>();
178 
179  bool limitDisplay=false;
180  if(vm.count("numMaxVoxel")){
181  limitDisplay=true;
182  }
183  unsigned int numDisplayedMax = vm["numMaxVoxel"].as<int>();
184 
185 
186  QApplication application(argc,argv);
187  typedef ViewerSnap<> Viewer;
188 
189  Viewer viewer(vm.count("doSnapShotAndExit"));
190  if(vm.count("doSnapShotAndExit")){
191  viewer.setSnapshotFileName(QString(vm["doSnapShotAndExit"].as<std::string>().c_str()));
192  }
193 
194  viewer.setWindowTitle("simple Volume Viewer");
195  viewer.show();
196 
197  typedef ImageSelector<Domain, unsigned char>::Type Image;
198  string extension = inputFilename.substr(inputFilename.find_last_of(".") + 1);
199  if(extension!="vol" && extension != "p3d" && extension != "pgm3D" && extension != "pgm3d" && extension != "sdp" && extension != "pgm"
200  #ifdef WITH_ITK
201  && extension !="dcm"
202 #endif
203 ){
204  trace.info() << "File extension not recognized: "<< extension << std::endl;
205  return 0;
206  }
207 
208  if(extension=="vol" || extension=="pgm3d" || extension=="pgm3D"
209 #ifdef WITH_ITK
210  || extension =="dcm"
211 #endif
212 ){
213  unsigned int numDisplayed=0;
214 
215 #ifdef WITH_ITK
216  int dicomMin = vm["dicomMin"].as<int>();
217  int dicomMax = vm["dicomMax"].as<int>();
218  typedef DGtal::functors::Rescaling<int ,unsigned char > RescalFCT;
219  Image image = extension == "dcm" ? DicomReader< Image, RescalFCT >::importDicom( inputFilename,
220  RescalFCT(dicomMin,
221  dicomMax,
222  0, 255) ) :
223  GenericReader<Image>::import( inputFilename );
224 #else
225  Image image = GenericReader<Image>::import (inputFilename );
226 #endif
227 
228  trace.info() << "Image loaded: "<<image<< std::endl;
229  Domain domain = image.domain();
230  GradientColorMap<long> gradient( thresholdMin, thresholdMax);
231  gradient.addColor(Color::Blue);
232  gradient.addColor(Color::Green);
233  gradient.addColor(Color::Yellow);
234  gradient.addColor(Color::Red);
235  for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
236  unsigned char val= image( (*it) );
237  if(limitDisplay && numDisplayed > numDisplayedMax)
238  break;
239  Color c= gradient(val);
240  if(val<=thresholdMax && val >=thresholdMin){
241  viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp),
242  Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp));
243  viewer << *it;
244  numDisplayed++;
245  }
246  }
247  }else if(extension=="sdp"){
248  vector<Z3i::RealPoint> vectVoxels = PointListReader<Z3i::RealPoint>::getPointsFromFile(inputFilename);
249  for(unsigned int i=0;i< vectVoxels.size(); i++){
250  viewer << vectVoxels.at(i);
251  }
252  }
253  if(vm.count("displayMesh")){
254  if(vm.count("colorMesh")){
255  std::vector<int> vcol= vm["colorMesh"].as<std::vector<int > >();
256  if(vcol.size()<4){
257  trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl;
258  return 0;
259  }
260  Color c(vcol[0], vcol[1], vcol[2], vcol[3]);
261  viewer.setFillColor(c);
262  }
263 
264  DGtal::Mesh<Z3i::RealPoint> aMesh(!vm.count("colorMesh"));
265  MeshReader<Z3i::RealPoint>::importOFFFile(vm["displayMesh"].as<std::string>(), aMesh);
266  viewer << aMesh;
267  }
268 
269  viewer << Viewer3D<>::updateDisplay;
270  if(vm.count("doSnapShotAndExit")){
271  // Appy cleaning just save the last snap
272  if(!viewer.restoreStateFromFile())
273  {
274  viewer.updateGL();
275  }
276  std::string name = vm["doSnapShotAndExit"].as<std::string>();
277  std::string extension = name.substr(name.find_last_of(".") + 1);
278  std::string basename = name.substr(0, name.find_last_of("."));
279  for(int i=0; i< viewer.snapshotCounter()-1; i++){
280  std::stringstream s;
281  s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension;
282  trace.info() << "erase temp file: " << s.str() << std::endl;
283  remove(s.str().c_str());
284  }
285  std::stringstream s;
286  s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension;
287  rename(s.str().c_str(), name.c_str());
288  return 0;
289  }
290 
291  return application.exec();
292 }
STL namespace.
Definition: ATu0v1.h:56