DGtalTools  0.9.4
3dVolViewer.cpp
1 
27 #include <iostream>
29 
30 #include "DGtal/base/Common.h"
31 #include "DGtal/base/BasicFunctors.h"
32 #include "DGtal/helpers/StdDefs.h"
33 #include "DGtal/io/readers/GenericReader.h"
34 #include "DGtal/io/viewers/Viewer3D.h"
35 #include "DGtal/io/DrawWithDisplay3DModifier.h"
36 #include "DGtal/io/readers/PointListReader.h"
37 #include "DGtal/io/readers/MeshReader.h"
38 
39 #include "DGtal/io/Color.h"
40 #include "DGtal/io/colormaps/GradientColorMap.h"
41 #include "DGtal/images/ImageSelector.h"
42 
43 #include <boost/program_options/options_description.hpp>
44 #include <boost/program_options/parsers.hpp>
45 #include <boost/program_options/variables_map.hpp>
46 
47 using namespace std;
48 using namespace DGtal;
49 using namespace Z3i;
50 
51 
111 template < typename Space = DGtal::Z3i::Space, typename KSpace = DGtal::Z3i::KSpace>
112 struct ViewerSnap: DGtal::Viewer3D <Space, KSpace>
113 {
114 
115  ViewerSnap(bool saveSnap): Viewer3D<Space, KSpace>(), mySaveSnap(saveSnap){
116  };
117 
118  virtual void
119  init(){
121  if(mySaveSnap){
122  QObject::connect(this, SIGNAL(drawFinished(bool)), this, SLOT(saveSnapshot(bool)));
123  }
124  };
125  bool mySaveSnap;
126 };
127 
128 
130 namespace po = boost::program_options;
131 
132 int main( int argc, char** argv )
133 {
134  // parse command line ----------------------------------------------
135  po::options_description general_opt("Allowed options are: ");
136  general_opt.add_options()
137  ("help,h", "display this message")
138  ("input,i", po::value<std::string>(), "vol file (.vol, .longvol .p3d, .pgm3d and if WITH_ITK is selected: dicom, dcm, mha, mhd) or sdp (sequence of discrete points). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." )
139  ("thresholdMin,m", po::value<int>()->default_value(0), "threshold min to define binary shape" )
140  ("thresholdMax,M", po::value<int>()->default_value(255), "threshold max to define binary shape" )
141  ("numMaxVoxel,n", po::value<int>()->default_value(500000), "set the maximal voxel number to be displayed." )
142  ("displayMesh", po::value<std::string>(), "display a Mesh given in OFF or OFS format. " )
143  ("colorMesh", po::value<std::vector <int> >()->multitoken(), "set the color of Mesh (given from displayMesh option) : r g b a " )
144  ("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." )
145  ("rescaleInputMin", po::value<DGtal::int64_t>()->default_value(0), "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).")
146  ("rescaleInputMax", po::value<DGtal::int64_t>()->default_value(255), "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).")
147  ("transparency,t", po::value<uint>()->default_value(255), "transparency") ;
148 
149  bool parseOK=true;
150  po::variables_map vm;
151  try{
152  po::store(po::parse_command_line(argc, argv, general_opt), vm);
153  }catch(const std::exception& ex){
154  parseOK=false;
155  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
156  }
157  po::notify(vm);
158  if( !parseOK || vm.count("help")||argc<=1)
159  {
160  std::cout << "Usage: " << argv[0] << " [input]\n"
161  << "Display volume file as a voxel set by using QGLviewer"<< endl
162  << general_opt << "\n"
163  << "Example: "<< std::endl
164  << " \t 3dVolViewer -i $DGtal/examples/samples/lobster.vol -m 60 -t 10" << endl;
165  return 0;
166  }
167 
168  if(! vm.count("input"))
169  {
170  trace.error() << " The file name was defined" << endl;
171  return 0;
172  }
173  string inputFilename = vm["input"].as<std::string>();
174  int thresholdMin = vm["thresholdMin"].as<int>();
175  int thresholdMax = vm["thresholdMax"].as<int>();
176  unsigned char transp = vm["transparency"].as<uint>();
177 
178  bool limitDisplay=false;
179  if(vm.count("numMaxVoxel")){
180  limitDisplay=true;
181  }
182  unsigned int numDisplayedMax = vm["numMaxVoxel"].as<int>();
183 
184 
185  QApplication application(argc,argv);
186  typedef ViewerSnap<> Viewer;
187 
188  Viewer viewer(vm.count("doSnapShotAndExit"));
189  if(vm.count("doSnapShotAndExit")){
190  viewer.setSnapshotFileName(QString(vm["doSnapShotAndExit"].as<std::string>().c_str()));
191  }
192 
193  viewer.setWindowTitle("simple Volume Viewer");
194  viewer.show();
195 
197  string extension = inputFilename.substr(inputFilename.find_last_of(".") + 1);
198  if(extension != "sdp")
199  {
200  unsigned int numDisplayed=0;
201  DGtal::int64_t rescaleInputMin = vm["rescaleInputMin"].as<DGtal::int64_t>();
202  DGtal::int64_t rescaleInputMax = vm["rescaleInputMax"].as<DGtal::int64_t>();
203 
205  Image image = GenericReader< Image >::importWithValueFunctor( inputFilename,RescalFCT(rescaleInputMin,
206  rescaleInputMax,
207  0, 255) );
208 
209 
210  trace.info() << "Image loaded: "<<image<< std::endl;
211  Domain domain = image.domain();
212  GradientColorMap<long> gradient( thresholdMin, thresholdMax);
213  gradient.addColor(Color::Blue);
214  gradient.addColor(Color::Green);
215  gradient.addColor(Color::Yellow);
216  gradient.addColor(Color::Red);
217  for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){
218  unsigned char val= image( (*it) );
219  if(limitDisplay && numDisplayed > numDisplayedMax)
220  break;
221  Color c= gradient(val);
222  if(val<=thresholdMax && val >=thresholdMin){
223  viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp),
224  Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp));
225  viewer << *it;
226  numDisplayed++;
227  }
228  }
229  }else if(extension=="sdp"){
230  vector<Z3i::RealPoint> vectVoxels = PointListReader<Z3i::RealPoint>::getPointsFromFile(inputFilename);
231  for(unsigned int i=0;i< vectVoxels.size(); i++){
232  viewer << vectVoxels.at(i);
233  }
234  }
235  if(vm.count("displayMesh")){
236  if(vm.count("colorMesh")){
237  std::vector<int> vcol= vm["colorMesh"].as<std::vector<int > >();
238  if(vcol.size()<4){
239  trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl;
240  return 0;
241  }
242  Color c(vcol[0], vcol[1], vcol[2], vcol[3]);
243  viewer.setFillColor(c);
244  }
245 
246  DGtal::Mesh<Z3i::RealPoint> aMesh(!vm.count("colorMesh"));
247  MeshReader<Z3i::RealPoint>::importOFFFile(vm["displayMesh"].as<std::string>(), aMesh);
248  viewer << aMesh;
249  }
250 
251  viewer << Viewer3D<>::updateDisplay;
252  if(vm.count("doSnapShotAndExit")){
253  // Appy cleaning just save the last snap
254  if(!viewer.restoreStateFromFile())
255  {
256  viewer.update();
257  }
258  std::string name = vm["doSnapShotAndExit"].as<std::string>();
259  std::string extension = name.substr(name.find_last_of(".") + 1);
260  std::string basename = name.substr(0, name.find_last_of("."));
261  for(int i=0; i< viewer.snapshotCounter()-1; i++){
262  std::stringstream s;
263  s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension;
264  trace.info() << "erase temp file: " << s.str() << std::endl;
265  remove(s.str().c_str());
266  }
267  std::stringstream s;
268  s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension;
269  rename(s.str().c_str(), name.c_str());
270  return 0;
271  }
272 
273  return application.exec();
274 }
virtual void show()
STL namespace.
Trace trace(traceWriterTerm)
std::ostream & info()
void green(const unsigned char aGreenValue)
const Domain & domain() const
void red(const unsigned char aRedValue)
std::ostream & error()
boost::int64_t int64_t
virtual void init()
typename Self::Domain Domain
void blue(const unsigned char aBlueValue)