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"    39 #include "DGtal/io/readers/DicomReader.h"    42 #include "sliceViewer.h"    43 #include "ui_sliceViewer.h"    47 #include "DGtal/io/viewers/Viewer3D.h"    48 #include "DGtal/io/viewers/DrawWithViewer3DModifier.h"    49 #include "DGtal/io/readers/PointListReader.h"    50 #include "DGtal/images/ConstImageAdapter.h"    51 #include <boost/program_options/options_description.hpp>    52 #include <boost/program_options/parsers.hpp>    53 #include <boost/program_options/variables_map.hpp>    57 using namespace DGtal;
    61 namespace po = boost::program_options;
   102 static const int MIN_ZOOM_FACTOR = 10.0;
   103 static const int MAX_ZOOM_FACTOR = 40.0;
   104 static const int INIT_SCALE1_ZOOM_FACTOR = 20.0;
   108 template <
typename TImage>
   111   typedef ConstImageAdapter<TImage, 
typename TImage::Domain,
   112                             functors::BasicDomainSubSampler<typename TImage::Domain, int, double>,
   116   std::vector<double> scales;
   117   scales.push_back(gridSize);
   118   scales.push_back(gridSize);  
   119   functors::BasicDomainSubSampler<typename TImage::Domain,  int, double> subSampler (anImage.domain(),
   120                                                                                              scales, Z2i::Point(0,0));
   121   typename TImage::Domain newDomain = subSampler.getSubSampledDomain();
   122   ConstImageAdapterForSubSampling  scaledImage (anImage, newDomain, subSampler, colFunctor );
   123   unsigned int height = scaledImage.domain().upperBound()[1]-scaledImage.domain().lowerBound()[1];
   124   unsigned int width = scaledImage.domain().upperBound()[0]-scaledImage.domain().lowerBound()[0];
   125   QImage res (width, height,QImage::Format_RGB32 );
   126   for(
unsigned int i=0; i<height; i++){
   127     for(
unsigned int j=0; j<width; j++){
   128       res.setPixel(j, height-i-1, scaledImage(Z2i::Point(j,i)+scaledImage.domain().lowerBound()));
   136                        DGtal::ImageContainerBySTLVector < DGtal::Z3i::Domain, unsigned char > *anImage,
   137                        const ColorMapFunctor &aFunctor, QWidget *parent, Qt::WindowFlags flags) :
   146   ui->verticalLayout_5->addWidget(aViewer);
   149   ui->_horizontalSliderZ->setMinimum(anImage->domain().lowerBound()[2]);
   150   ui->_horizontalSliderZ->setMaximum(anImage->domain().upperBound()[2]);
   151   ui->_horizontalSliderZ->setValue(anImage->domain().lowerBound()[2]);
   153   ui->_horizontalSliderY->setMinimum(anImage->domain().lowerBound()[1]);
   154   ui->_horizontalSliderY->setMaximum(anImage->domain().upperBound()[1]);
   155   ui->_horizontalSliderY->setValue(anImage->domain().lowerBound()[1]);
   157   ui->_horizontalSliderX->setMinimum(anImage->domain().lowerBound()[0]);
   158   ui->_horizontalSliderX->setMaximum(anImage->domain().upperBound()[0]);
   159   ui->_horizontalSliderX->setValue(anImage->domain().lowerBound()[0]);
   161   ui->_zoomXSlider->setMinimum( MIN_ZOOM_FACTOR);
   162   ui->_zoomXSlider->setMaximum( MAX_ZOOM_FACTOR);
   163   ui->_zoomXSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   165   ui->_zoomYSlider->setMinimum(MIN_ZOOM_FACTOR);
   166   ui->_zoomYSlider->setMaximum(MAX_ZOOM_FACTOR);
   167   ui->_zoomYSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   169   ui->_zoomZSlider->setMinimum(MIN_ZOOM_FACTOR);
   170   ui->_zoomZSlider->setMaximum(MAX_ZOOM_FACTOR);
   171   ui->_zoomZSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   173   QObject::connect(
ui->_horizontalSliderX, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateSliceImageX()));
   174   QObject::connect(
ui->_horizontalSliderY, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateSliceImageY()));
   175   QObject::connect(
ui->_horizontalSliderZ, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateSliceImageZ()));
   176   QObject::connect(
ui->_zoomXSlider, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateZoomImageX()));
   177   QObject::connect(
ui->_zoomYSlider, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateZoomImageY()));
   178   QObject::connect(
ui->_zoomZSlider, SIGNAL(valueChanged(
int)), 
this, SLOT(
updateZoomImageZ()));
   222   ui->ImageProjX->setPixmap(aPixMap);
   225   ui->ImageProjY->setPixmap(aPixMap);
   228   ui->ImageProjZ->setPixmap(aPixMap);
   246   ui->_zoomXSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   251   ui->_zoomYSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   256   ui->_zoomZSlider->setValue(INIT_SCALE1_ZOOM_FACTOR);
   263   double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/
ui->_zoomXSlider->value();
   265   QString gridStr = QString::number(gridSize, 
'f', 3);
   266   QString scaleStr = QString::number(1.0/gridSize, 
'f', 3);
   267   ui->_groupBoxX->setTitle(QString(
"Slice View X: sampling grid size: ").append(gridStr).
   268                            append(QString(
" (zoom x "). append(scaleStr).append(QString(
")") )));
   271   double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/
ui->_zoomYSlider->value();
   273   QString gridStr = QString::number(gridSize, 
'f', 3);
   274   QString scaleStr = QString::number(1.0/gridSize, 
'f', 3);
   275   ui->_groupBoxY->setTitle(QString(
"Slice View Y: sampling grid size: ").append(gridStr).
   276                            append(QString(
" (zoom x "). append(scaleStr).append(QString(
")") )));
   280   double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/
ui->_zoomZSlider->value();
   282   QString gridStr = QString::number(gridSize, 
'f', 3);
   283   QString scaleStr = QString::number(1.0/gridSize, 
'f', 3);
   284   ui->_groupBoxZ->setTitle(QString(
"Slice View Z: sampling grid size: ").append(gridStr).
   285                            append(QString(
" (zoom x "). append(scaleStr).append(QString(
")") )));
   291   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(0);
   292   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   293                               invFunctor(
myImage3D->domain().upperBound()));
   294   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(0);
   295   const functors::Identity identityFunctor{};
   297   QImage anImage = getImage(sliceImage, gridSize, 
myColorMap);
   302   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(1);
   303   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   304                               invFunctor(
myImage3D->domain().upperBound()));
   305   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(1);
   306   const functors::Identity identityFunctor{};
   309   QImage anImage = getImage(sliceImage, gridSize, 
myColorMap);
   315   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(2);
   316   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   317                               invFunctor(
myImage3D->domain().upperBound()));
   318   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(2);
   319   const functors::Identity identityFunctor{};
   321   QImage anImage = getImage(sliceImage, gridSize, 
myColorMap );
   327   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(0);
   328   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   329                               invFunctor(
myImage3D->domain().upperBound()));
   330   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(0);
   331   const functors::Identity identityFunctor{};
   334   double gridSize = ((double)INIT_SCALE1_ZOOM_FACTOR)/
ui->_zoomXSlider->value();
   335   QImage anImage = getImage(sliceImage, gridSize,
myColorMap);
   337   Z3i::Point imageOrigin = 
myImage3D->domain().lowerBound();
   339     (*myViewer) << DGtal::AddTextureImage2DWithFunctor<SliceImageAdapter, ColorMapFunctor, Z3i::Space, Z3i::KSpace>(sliceImage, 
myColorMap, DGtal::Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode);
   340     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(0, DGtal::Viewer3D<>::xDirection, sliceNumber,
   341                                                                imageOrigin[1], imageOrigin[2]);
   342     (*myViewer) << Viewer3D<>::updateDisplay;
   344     (*myViewer) << DGtal::UpdateImageData< SliceImageAdapter, ColorMapFunctor > (0, sliceImage, 0, 0, 0 ,0,  DGtal::Viewer3D<>::xDirection, 
myColorMap);
   345     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(0, DGtal::Viewer3D<>::xDirection, sliceNumber, imageOrigin[1],
   348     (*myViewer).updateList(init);
   349     (*myViewer).update();
   358   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(1);
   359   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   360                               invFunctor(
myImage3D->domain().upperBound()));
   361   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(1);
   362   const functors::Identity identityFunctor{};
   365   double gridSize = ((double)INIT_SCALE1_ZOOM_FACTOR)/
ui->_zoomYSlider->value();
   366   QImage anImage = getImage(sliceImage, gridSize, 
myColorMap);
   368   Z3i::Point imageOrigin = 
myImage3D->domain().lowerBound();
   370     (*myViewer) << DGtal::AddTextureImage2DWithFunctor<SliceImageAdapter, ColorMapFunctor, Z3i::Space, Z3i::KSpace>(sliceImage, 
myColorMap, DGtal::Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode);
   371     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(1, DGtal::Viewer3D<>::yDirection, imageOrigin[0],
   372                                                                sliceNumber, imageOrigin[2]);
   373     (*myViewer) << Viewer3D<>::updateDisplay;
   375     (*myViewer) << DGtal::UpdateImageData< SliceImageAdapter, ColorMapFunctor > (1, sliceImage, 0,0, 0, 0,  DGtal::Viewer3D<>::yDirection, 
myColorMap);
   376     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(1, DGtal::Viewer3D<>::yDirection, imageOrigin[0],
   377                                                                sliceNumber, imageOrigin[2]);
   378     (*myViewer).updateList(init);
   379     (*myViewer).update();
   387   DGtal::functors::Projector<DGtal::Z2i::Space>  invFunctor; invFunctor.initRemoveOneDim(2);
   388   DGtal::Z2i::Domain domain2D(invFunctor(
myImage3D->domain().lowerBound()),
   389                               invFunctor(
myImage3D->domain().upperBound()));
   390   DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(sliceNumber); aSliceFunctor.initAddOneDim(2);
   391   const functors::Identity identityFunctor{};
   393   double gridSize = (double)INIT_SCALE1_ZOOM_FACTOR/
ui->_zoomZSlider->value();
   394   QImage anImage = getImage(sliceImage, gridSize, 
myColorMap);
   396   Z3i::Point imageOrigin = 
myImage3D->domain().lowerBound();
   398     (*myViewer) << DGtal::AddTextureImage2DWithFunctor<SliceImageAdapter, ColorMapFunctor, Z3i::Space, Z3i::KSpace>(sliceImage, 
myColorMap, DGtal::Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode);
   399     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(2, DGtal::Viewer3D<>::zDirection, imageOrigin[0],
   400                                                                imageOrigin[1], sliceNumber);
   402     (*myViewer) << Viewer3D<>::updateDisplay;
   404     (*myViewer) << DGtal::UpdateImageData< SliceImageAdapter,ColorMapFunctor > (2, sliceImage, 0,0, 0, 0,  DGtal::Viewer3D<>::zDirection,
   406     (*myViewer) << DGtal::UpdateImagePosition< Space, KSpace >(2, DGtal::Viewer3D<>::zDirection, imageOrigin[0],
   407                                                                imageOrigin[1], sliceNumber);
   408     (*myViewer).updateList(init);
   409     (*myViewer).update();
   417 int main( 
int argc, 
char** argv )
   420   po::options_description general_opt(
"Allowed options are: ");
   421   general_opt.add_options()
   422     (
"help,h", 
"display this message")
   423     (
"input,i", po::value<std::string>(), 
"vol file (.vol) , pgm3d (.p3d or .pgm3d, pgm (with 3 dims)) file or sdp (sequence of discrete points)" )
   424     (
"hueColorMap", 
"use hue color map to display images." )
   425     (
"gradHotColorMap", 
"use hot gradient color map to display images." )
   426     (
"gradCoolColorMap", 
"use cool gradient color map to display images." )
   429     (
"dicomMin", po::value<int>()->default_value(-1000), 
"set minimum density threshold on Hounsfield scale")
   430     (
"dicomMax", po::value<int>()->default_value(3000), 
"set maximum density threshold on Hounsfield scale")
   435   po::variables_map vm;
   437     po::store(po::parse_command_line(argc, argv, general_opt), vm);
   438   }
catch(
const std::exception& ex){
   440     trace.info()<< 
"Error checking program options: "<< ex.what()<< endl;
   443   if( !parseOK || vm.count(
"help")||argc<=1)
   445       std::cout << 
"Usage: " << argv[0] << 
" [input]\n"   446                 << 
"Displays volume file with slice image by using QT and QGLviewer"<< endl
   447                 << general_opt << 
"\n";
   451   if(! vm.count(
"input"))
   453       trace.error() << 
" The file name was defined" << endl;
   456   string inputFilename = vm[
"input"].as<std::string>();
   459   typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > 
Image3D;
   460   typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > 
Image2D;
   462   string extension = inputFilename.substr(inputFilename.find_last_of(
".") + 1);
   463   if(extension!=
"vol" && extension != 
"p3d" && extension != 
"pgm3D" && extension != 
"pgm3d" && extension != 
"sdp" && extension != 
"pgm"   468     trace.info() << 
"File extension not recognized: "<< extension << std::endl;
   472   if(extension==
"vol" || extension==
"pgm3d" || extension==
"pgm3D"   479     int dicomMin = vm[
"dicomMin"].as<
int>();
   480     int dicomMax = vm[
"dicomMax"].as<
int>();
   481     typedef functors::Rescaling<int ,unsigned char > RescalFCT;
   482     Image3D image = extension == 
"dcm" ? DicomReader< Image3D,  RescalFCT  >::importDicom( inputFilename,
   486       GenericReader<Image3D>::import( inputFilename );
   487     trace.info() << 
"Imported ITK..."<< std::endl;
   489     Image3D image = GenericReader<Image3D>::import (inputFilename );
   490     trace.info() << 
"Imported..."<< std::endl;
   495     QApplication application(argc,argv);
   496     Viewer3D<> *viewer = 
new Viewer3D<>();
   497     bool usehm = vm.count(
"hueColorMap");
   498     bool usegh = vm.count(
"gradHotColorMap");
   499     bool usegc = vm.count(
"gradCoolColorMap");
   505     w.setWindowTitle ( QString(
"sliceViewer"));
   510     Z3i::Point size = image.domain().upperBound() - image.domain().lowerBound();
   511     Z3i::Point center = image.domain().lowerBound()+size/2;
   512     unsigned int maxDist = std::max(std::max(size[2], size[1]), size[2]);
   513     viewer->camera()->setPosition(qglviewer::Vec(center[0],center[1], 
   514                                                  center[2] + 2.0*maxDist));
   515     viewer->camera()->setSceneCenter(qglviewer::Vec(center[0],center[1],center[2]));
 
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 updateSliceImageZ(int sliceNumber, bool init)
 
void updateSliceImageX(int sliceNumber, bool init)
 
DGtal::ConstImageAdapter< Image3D, Image2D::Domain, DGtal::functors::Projector< DGtal::Z3i::Space >, Image3D::Value, DGtal::functors::Identity > SliceImageAdapter
 
DGtal::ImageContainerBySTLVector< DGtal::Z2i::Domain, unsigned char > Image2D
 
void changeCoolColorMap()
 
ColorMapFunctor myColorMap
 
void setScale1_1_ImageZ()
 
void updateSliceImageY(int sliceNumber, bool init)
 
void setImageProjY(const QPixmap &aPixMap)
 
void setImageProjZ(const QPixmap &aPixMap)
 
void updateAllDisplayedImages()
 
void setScale1_1_ImageX()
 
DGtal::ImageContainerBySTLVector< DGtal::Z3i::Domain, unsigned char > Image3D
 
void setImageProjX(const QPixmap &aPixMap)