DGtalTools  0.9.4
sliceViewer.cpp
1 
28 #include <iostream>
30 #ifndef Q_MOC_RUN
31 #include "DGtal/base/Common.h"
32 #include "DGtal/base/BasicFunctors.h"
33 #include "DGtal/helpers/StdDefs.h"
34 #include "DGtal/io/readers/GenericReader.h"
35 #include "DGtal/io/Color.h"
36 #include "DGtal/io/DrawWithDisplay3DModifier.h"
37 #endif
38 
39 #include "sliceViewer.h"
40 #include "ui_sliceViewer.h"
41 
42 
43 #ifndef Q_MOC_RUN
44 #include "DGtal/io/viewers/Viewer3D.h"
45 #include "DGtal/io/viewers/DrawWithViewer3DModifier.h"
46 #include "DGtal/io/readers/PointListReader.h"
47 #include "DGtal/images/ConstImageAdapter.h"
48 #include <boost/program_options/options_description.hpp>
49 #include <boost/program_options/parsers.hpp>
50 #include <boost/program_options/variables_map.hpp>
51 #endif
52 
53 using namespace std;
54 using namespace DGtal;
55 using namespace Z3i;
56 
58 namespace po = boost::program_options;
59 
60 
61 
103 // Set to define slider int value and grid size
104 
105 static const int MIN_ZOOM_FACTOR = 10.0;
106 static const int MAX_ZOOM_FACTOR = 40.0;
107 static const int INIT_SCALE1_ZOOM_FACTOR = 20.0;
108 
109 
110 
111 template <typename TImage>
112 static QImage
113 getImage(const TImage &anImage, double gridSize, const MainWindow::ColorMapFunctor &colFunctor ){
114  typedef ConstImageAdapter<TImage, typename TImage::Domain,
116  unsigned int,
117  MainWindow::ColorMapFunctor> ConstImageAdapterForSubSampling;
118 
119  std::vector<double> scales;
120  scales.push_back(gridSize);
121  scales.push_back(gridSize);
123  scales, Z2i::Point(0,0));
124  typename TImage::Domain newDomain = subSampler.getSubSampledDomain();
125  ConstImageAdapterForSubSampling scaledImage (anImage, newDomain, subSampler, colFunctor );
126  unsigned int height = scaledImage.domain().upperBound()[1]-scaledImage.domain().lowerBound()[1];
127  unsigned int width = scaledImage.domain().upperBound()[0]-scaledImage.domain().lowerBound()[0];
128  QImage res (width, height,QImage::Format_RGB32 );
129  for(unsigned int i=0; i<height; i++){
130  for(unsigned int j=0; j<width; j++){
131  res.setPixel(j, height-i-1, scaledImage(Z2i::Point(j,i)+scaledImage.domain().lowerBound()));
132  }
133  }
134  return res;
135 }
136 
137 
140  const ColorMapFunctor &aFunctor, QWidget *parent, Qt::WindowFlags flags) :
141  QMainWindow(parent),
142  ui(new Ui::MainWindow),
143  myViewer(aViewer),
144  myImage3D(anImage),
145  myColorMap(aFunctor)
146 {
147 
148  ui->setupUi(this);
149  ui->verticalLayout_5->addWidget(aViewer);
150 
151 
152  ui->_horizontalSliderZ->setMinimum(anImage->domain().lowerBound()[2]);
153  ui->_horizontalSliderZ->setMaximum(anImage->domain().upperBound()[2]);
154  ui->_horizontalSliderZ->setValue(anImage->domain().lowerBound()[2]);
155 
156  ui->_horizontalSliderY->setMinimum(anImage->domain().lowerBound()[1]);
157  ui->_horizontalSliderY->setMaximum(anImage->domain().upperBound()[1]);
158  ui->_horizontalSliderY->setValue(anImage->domain().lowerBound()[1]);
159 
160  ui->_horizontalSliderX->setMinimum(anImage->domain().lowerBound()[0]);
161  ui->_horizontalSliderX->setMaximum(anImage->domain().upperBound()[0]);
162  ui->_horizontalSliderX->setValue(anImage->domain().lowerBound()[0]);
163 
164  ui->_zoomXSlider->setMinimum( MIN_ZOOM_FACTOR);
165  ui->_zoomXSlider->setMaximum( MAX_ZOOM_FACTOR);
166  ui->_zoomXSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
167 
168  ui->_zoomYSlider->setMinimum(MIN_ZOOM_FACTOR);
169  ui->_zoomYSlider->setMaximum(MAX_ZOOM_FACTOR);
170  ui->_zoomYSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
171 
172  ui->_zoomZSlider->setMinimum(MIN_ZOOM_FACTOR);
173  ui->_zoomZSlider->setMaximum(MAX_ZOOM_FACTOR);
174  ui->_zoomZSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
175 
176  QObject::connect(ui->_horizontalSliderX, SIGNAL(valueChanged(int)), this, SLOT(updateSliceImageX()));
177  QObject::connect(ui->_horizontalSliderY, SIGNAL(valueChanged(int)), this, SLOT(updateSliceImageY()));
178  QObject::connect(ui->_horizontalSliderZ, SIGNAL(valueChanged(int)), this, SLOT(updateSliceImageZ()));
179  QObject::connect(ui->_zoomXSlider, SIGNAL(valueChanged(int)), this, SLOT(updateZoomImageX()));
180  QObject::connect(ui->_zoomYSlider, SIGNAL(valueChanged(int)), this, SLOT(updateZoomImageY()));
181  QObject::connect(ui->_zoomZSlider, SIGNAL(valueChanged(int)), this, SLOT(updateZoomImageZ()));
182 
183  QObject::connect(ui->_scale1ButtonX, SIGNAL(clicked()), this, SLOT(setScale1_1_ImageX()));
184  QObject::connect(ui->_scale1ButtonY, SIGNAL(clicked()), this, SLOT(setScale1_1_ImageY()));
185  QObject::connect(ui->_scale1ButtonZ, SIGNAL(clicked()), this, SLOT(setScale1_1_ImageZ()));
186 
187  QObject::connect(ui->_CoolButton, SIGNAL(clicked()), this, SLOT(changeCoolColorMap()));
188  QObject::connect(ui->_HotButton, SIGNAL(clicked()), this, SLOT(changeHotColorMap()));
189  QObject::connect(ui->_HueButton, SIGNAL(clicked()), this, SLOT(changeHueColorMap()));
190  QObject::connect(ui->_NormalButton, SIGNAL(clicked()), this, SLOT(changeNormalColorMap()));
191 
192 
193 }
194 
196 {
197  delete ui;
198 }
199 
204 }
208 }
209 
213 }
217 }
221 }
222 
223 
224 void MainWindow::setImageProjX(const QPixmap &aPixMap){
225  ui->ImageProjX->setPixmap(aPixMap);
226 }
227 void MainWindow::setImageProjY(const QPixmap &aPixMap){
228  ui->ImageProjY->setPixmap(aPixMap);
229 }
230 void MainWindow::setImageProjZ(const QPixmap &aPixMap){
231  ui->ImageProjZ->setPixmap(aPixMap);
232 }
233 
234 
236  updateSliceImageX(ui->_horizontalSliderX->value(), false);
237 }
238 
240  updateSliceImageY(ui->_horizontalSliderY->value(), false);
241 }
242 
244  updateSliceImageZ(ui->_horizontalSliderZ->value(), false);
245 }
246 
247 
249  ui->_zoomXSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
251 }
252 
254  ui->_zoomYSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
256 }
257 
259  ui->_zoomZSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
261 }
262 
263 
264 
266  double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/ui->_zoomXSlider->value();
267  updateZoomImageX(ui->_horizontalSliderX->value(), gridSize );
268  QString gridStr = QString::number(gridSize, 'f', 3);
269  QString scaleStr = QString::number(1.0/gridSize, 'f', 3);
270  ui->_groupBoxX->setTitle(QString("Slice View X: sampling grid size: ").append(gridStr).
271  append(QString(" (zoom x "). append(scaleStr).append(QString(")") )));
272 }
274  double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/ui->_zoomYSlider->value();
275  updateZoomImageY(ui->_horizontalSliderY->value(), gridSize );
276  QString gridStr = QString::number(gridSize, 'f', 3);
277  QString scaleStr = QString::number(1.0/gridSize, 'f', 3);
278  ui->_groupBoxY->setTitle(QString("Slice View Y: sampling grid size: ").append(gridStr).
279  append(QString(" (zoom x "). append(scaleStr).append(QString(")") )));
280 
281 }
283  double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/ui->_zoomZSlider->value();
284  updateZoomImageZ(ui->_horizontalSliderZ->value(), gridSize );
285  QString gridStr = QString::number(gridSize, 'f', 3);
286  QString scaleStr = QString::number(1.0/gridSize, 'f', 3);
287  ui->_groupBoxZ->setTitle(QString("Slice View Z: sampling grid size: ").append(gridStr).
288  append(QString(" (zoom x "). append(scaleStr).append(QString(")") )));
289 
290 }
291 
292 
293 void MainWindow::updateZoomImageX(int sliceNumber, double gridSize){
295  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
296  invFunctor(myImage3D->domain().upperBound()));
297  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(0);
298  const functors::Identity identityFunctor{};
299  SliceImageAdapter sliceImage( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
300  QImage anImage = getImage(sliceImage, gridSize, myColorMap);
301  setImageProjX(QPixmap::fromImage(anImage));
302 }
303 
304 void MainWindow::updateZoomImageY(int sliceNumber, double gridSize){
306  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
307  invFunctor(myImage3D->domain().upperBound()));
308  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(1);
309  const functors::Identity identityFunctor{};
310  SliceImageAdapter sliceImage( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
311 
312  QImage anImage = getImage(sliceImage, gridSize, myColorMap);
313  setImageProjY(QPixmap::fromImage(anImage));
314 }
315 
316 
317 void MainWindow::updateZoomImageZ(int sliceNumber, double gridSize){
319  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
320  invFunctor(myImage3D->domain().upperBound()));
321  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(2);
322  const functors::Identity identityFunctor{};
323  SliceImageAdapter sliceImage( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
324  QImage anImage = getImage(sliceImage, gridSize, myColorMap );
325  setImageProjZ(QPixmap::fromImage(anImage));
326 }
327 
328 
329 void MainWindow::updateSliceImageX(int sliceNumber, bool init){
331  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
332  invFunctor(myImage3D->domain().upperBound()));
333  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(0);
334  const functors::Identity identityFunctor{};
335  SliceImageAdapter sliceImage ( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
336 
337  double gridSize = ((double)INIT_SCALE1_ZOOM_FACTOR)/ui->_zoomXSlider->value();
338  QImage anImage = getImage(sliceImage, gridSize,myColorMap);
339  setImageProjX(QPixmap::fromImage(anImage));
340  Z3i::Point imageOrigin = myImage3D->domain().lowerBound();
341  if(init){
344  imageOrigin[1], imageOrigin[2]);
345  (*myViewer) << Viewer3D<>::updateDisplay;
346  }else{
348  (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(0, DGtal::Viewer3D<>::xDirection, sliceNumber, imageOrigin[1],
349  imageOrigin[2]);
350 
351  (*myViewer).updateList(init);
352  (*myViewer).update();
353  }
354 
355 
356 }
357 
358 
359 void MainWindow::updateSliceImageY( int sliceNumber, bool init){
360 
362  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
363  invFunctor(myImage3D->domain().upperBound()));
364  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(1);
365  const functors::Identity identityFunctor{};
366  SliceImageAdapter sliceImage( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
367 
368  double gridSize = ((double)INIT_SCALE1_ZOOM_FACTOR)/ui->_zoomYSlider->value();
369  QImage anImage = getImage(sliceImage, gridSize, myColorMap);
370  setImageProjY(QPixmap::fromImage(anImage));
371  Z3i::Point imageOrigin = myImage3D->domain().lowerBound();
372  if(init){
375  sliceNumber, imageOrigin[2]);
376  (*myViewer) << Viewer3D<>::updateDisplay;
377  }else{
379  (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(1, DGtal::Viewer3D<>::yDirection, imageOrigin[0],
380  sliceNumber, imageOrigin[2]);
381  (*myViewer).updateList(init);
382  (*myViewer).update();
383  }
384 
385 }
386 
387 
388 void MainWindow::updateSliceImageZ(int sliceNumber, bool init){
389 
391  DGtal::Z2i::Domain domain2D(invFunctor(myImage3D->domain().lowerBound()),
392  invFunctor(myImage3D->domain().upperBound()));
393  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(2);
394  const functors::Identity identityFunctor{};
395  SliceImageAdapter sliceImage( *myImage3D, domain2D, aSliceFunctor, identityFunctor );
396  double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/ui->_zoomZSlider->value();
397  QImage anImage = getImage(sliceImage, gridSize, myColorMap);
398  setImageProjZ(QPixmap::fromImage(anImage));
399  Z3i::Point imageOrigin = myImage3D->domain().lowerBound();
400  if(init){
403  imageOrigin[1], sliceNumber);
404 
405  (*myViewer) << Viewer3D<>::updateDisplay;
406  }else{
408  myColorMap);
409  (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(2, DGtal::Viewer3D<>::zDirection, imageOrigin[0],
410  imageOrigin[1], sliceNumber);
411  (*myViewer).updateList(init);
412  (*myViewer).update();
413  }
414 
415 
416 }
417 
418 
419 
420 int main( int argc, char** argv )
421 {
422 
423  po::options_description general_opt("Allowed options are: ");
424  general_opt.add_options()
425  ("help,h", "display this message")
426  ("input,i", po::value<std::string>(), "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." )
427  ("hueColorMap", "use hue color map to display images." )
428  ("gradHotColorMap", "use hot gradient color map to display images." )
429  ("gradCoolColorMap", "use cool gradient color map to display images." )
430  ("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).")
431  ("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).");
432 
433  bool parseOK=true;
434  po::variables_map vm;
435  try{
436  po::store(po::parse_command_line(argc, argv, general_opt), vm);
437  }catch(const std::exception& ex){
438  parseOK=false;
439  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
440  }
441  po::notify(vm);
442  if( !parseOK || vm.count("help")||argc<=1)
443  {
444  std::cout << "Usage: " << argv[0] << " [input]\n"
445  << "Displays volume file with slice image by using QT and QGLviewer"<< endl
446  << general_opt << "\n";
447  return 0;
448  }
449 
450  if(! vm.count("input"))
451  {
452  trace.error() << " The file name was defined" << endl;
453  return 0;
454  }
455  string inputFilename = vm["input"].as<std::string>();
456 
457 
460 
461  DGtal::int64_t rescaleInputMin = vm["rescaleInputMin"].as<DGtal::int64_t>();
462  DGtal::int64_t rescaleInputMax = vm["rescaleInputMax"].as<DGtal::int64_t>();
463 
465  Image3D image = GenericReader< Image3D >::importWithValueFunctor( inputFilename,RescalFCT(rescaleInputMin,
466  rescaleInputMax,
467  0, 255) );
468  trace.info() << "Imported..."<< std::endl;
469 
470 
471 
472 
473 
474  QApplication application(argc,argv);
475  Viewer3D<> *viewer = new Viewer3D<>();
476  bool usehm = vm.count("hueColorMap");
477  bool usegh = vm.count("gradHotColorMap");
478  bool usegc = vm.count("gradCoolColorMap");
479 
483  MainWindow::Id), 0,0);
484  w.setWindowTitle ( QString("sliceViewer"));
485  w.updateSliceImageX( image.domain().lowerBound()[0], true);
486  w.updateSliceImageY( image.domain().lowerBound()[1], true);
487  w.updateSliceImageZ( image.domain().lowerBound()[2], true);
488  w.show();
489  Z3i::Point size = image.domain().upperBound() - image.domain().lowerBound();
490  Z3i::Point center = image.domain().lowerBound()+size/2;
491  unsigned int maxDist = std::max(std::max(size[2], size[1]), size[2]);
492  viewer->camera()->setPosition(qglviewer::Vec(center[0],center[1],
493  center[2] + 2.0*maxDist));
494  viewer->camera()->setSceneCenter(qglviewer::Vec(center[0],center[1],center[2]));
495  application.exec();
496  delete viewer;
497 
498 }
499 
Ui::MainWindow * ui
Definition: sliceViewer.h:142
void setScale1_1_ImageY()
void changeNormalColorMap()
MainWindow(DGtal::Viewer3D<> *viewer, DGtal::ImageContainerBySTLVector< DGtal::Z3i::Domain, unsigned char > *myImage3D, const ColorMapFunctor &aFunctor, QWidget *parent=0, Qt::WindowFlags flags=0)
void updateZoomImageX()
Definition: sliceViewer.h:43
STL namespace.
void initRemoveOneDim(const Dimension &dimRemoved)
void changeCoolColorMap()
void updateZoomImageY()
ColorMapFunctor myColorMap
Definition: sliceViewer.h:145
Image3D * myImage3D
Definition: sliceViewer.h:144
void setScale1_1_ImageZ()
void updateSliceImageX()
void setImageProjY(const QPixmap &aPixMap)
void updateSliceImageZ()
const Point & upperBound() const
void setImageProjZ(const QPixmap &aPixMap)
Trace trace(traceWriterTerm)
std::ostream & info()
void initAddOneDim(const Dimension &newDim)
const Domain & domain() const
void changeHotColorMap()
void updateAllDisplayedImages()
void setScale1_1_ImageX()
void updateZoomImageZ()
void changeHueColorMap()
const Point & lowerBound() const
std::ostream & error()
boost::int64_t int64_t
void updateSliceImageY()
void setImageProjX(const QPixmap &aPixMap)