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