]> Creatis software - clitk.git/commitdiff
Implemented alternative to former split: split on open.
authorsrit <srit>
Thu, 21 Oct 2010 12:56:57 +0000 (12:56 +0000)
committersrit <srit>
Thu, 21 Oct 2010 12:56:57 +0000 (12:56 +0000)
vv/qt_ui/vvMainWindow.ui
vv/vvConstants.h
vv/vvImageReader.cxx
vv/vvImageReader.h
vv/vvImageReader.txx
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvSlicerManager.cxx
vv/vvSlicerManager.h

index 0dffe7b081f482b0c7f4f2db8932b2112e250039..fb7ff7655eddf1ecd8697a3885b59f43722972f5 100644 (file)
     </property>
     <addaction name="actionLoad_images"/>
     <addaction name="actionOpen_Image_With_Time"/>
+    <addaction name="actionMerge_images_as_n_dim_t"/>
     <addaction name="separator"/>
+    <addaction name="actionSlice_Image_As_Multiple_Images"/>
     <addaction name="actionOpen_Multiple_Images_As_One"/>
-    <addaction name="actionMerge_images_as_n_dim_t"/>
     <addaction name="separator"/>
     <addaction name="actionOpen_Dicom"/>
     <addaction name="actionOpen_Dicom_Struct"/>
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Open several xD images into a single (x+1) D</string>
+    <string>Merge several xD images into a single (x+1)D image</string>
+   </property>
+  </action>
+  <action name="actionSlice_Image_As_Multiple_Images">
+   <property name="icon">
+    <iconset resource="../vvIcons.qrc">
+     <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
+   </property>
+   <property name="text">
+    <string>Slice a xD image into several (x-1)D images</string>
    </property>
   </action>
   <action name="actionOpen_one_Image_as_Multiple">
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Open several xD images into a single xD + t</string>
+    <string>Open several xD images into a single xD+t images</string>
    </property>
   </action>
   <action name="actionAdd_fusion_image">
index be3652b5e46d1d2a37f18f53e1be280ae071263f..dfc7b758170ca67e5c0d26cdb8cfdf54bc03c605 100644 (file)
@@ -25,6 +25,7 @@ typedef enum _IMAGETYPE {
 IMAGE = 20,
 DICOM,
 MERGED,
+SLICED,
 IMAGEWITHTIME,
 MERGEDWITHTIME,
 VECTORFIELD,
index 17ed757b7af7a13b904c53ed1deb9984a7f39afe..8bbdf251b57355a40b466065e913596e6ec0d7b9 100644 (file)
@@ -31,6 +31,7 @@ vvImageReader::vvImageReader()
   mInputFilenames.resize(0);
   mLastError = "";
   mType = UNDEFINEDIMAGETYPE;
+  mSlice = 0;
 }
 //------------------------------------------------------------------------------
 
index 99d302ae385a35f3150dd13877c95350fba656dc..b50d66b3be748c51208c537cfc4d001d4957402e 100644 (file)
@@ -42,12 +42,13 @@ public:
         return mLastError;
     }
 
+    void SetSlice(unsigned int i) { mSlice = i; }
+
     //====================================================================
     // Main function
     void Update();
     void Update(LoadedImageType type);
     void Update(int dim, std::string InputPixelType, LoadedImageType type);
-    //void Extract(int dim, std::string InputPixelType, int slice);
 
 protected:
     void run();
@@ -55,6 +56,7 @@ protected:
     std::vector<std::string> mInputFilenames;
     ///Method used to load the image, see vvConstants.h for definition
     LoadedImageType mType;
+    unsigned int mSlice;
     itk::Command::Pointer mObserver;
 
     std::string mLastError;
index 75fab2de8253e06df9920996612b3941ee2113f6..31937bfbc229fe83919f721cbeeb4dce6f772c1e 100644 (file)
@@ -75,13 +75,12 @@ void vvImageReader::UpdateWithDimAndInputPixelType()
     // one at the time to avoid excessive
     // memory use
   {
-      mImage=vvImage::New();
-      for (std::vector<std::string>::const_iterator i=mInputFilenames.begin(); i!=mInputFilenames.end(); i++) {
+    mImage=vvImage::New();
+    for (std::vector<std::string>::const_iterator i=mInputFilenames.begin(); i!=mInputFilenames.end(); i++) {
       typedef itk::Image< InputPixelType, VImageDimension-1 > InputImageType;
       typedef itk::ImageFileReader<InputImageType> ReaderType;
       typename ReaderType::Pointer reader = ReaderType::New();
       reader->ReleaseDataFlagOn();
-      std::cout << (*i) << std::endl;
       reader->SetFileName(*i);
       try {
         reader->Update();
@@ -95,6 +94,40 @@ void vvImageReader::UpdateWithDimAndInputPixelType()
       }
       mImage->AddItkImage<InputImageType>(reader->GetOutput());
     }
+  } else if (mType == SLICED) {
+    mImage=vvImage::New();
+    typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
+    typedef itk::ImageFileReader<InputImageType> ReaderType;
+    typename ReaderType::Pointer reader = ReaderType::New();
+    reader->SetFileName(mInputFilenames[0]);
+    reader->UpdateOutputInformation();
+
+    typedef itk::Image< InputPixelType, VImageDimension-1 > SlicedImageType;
+    typedef itk::ExtractImageFilter<InputImageType, SlicedImageType> FilterType;
+
+    typename InputImageType::RegionType inputRegion = reader->GetOutput()->GetLargestPossibleRegion();
+    typename InputImageType::SizeType inputSize = inputRegion.GetSize();
+    typename InputImageType::IndexType start = inputRegion.GetIndex();
+    typename InputImageType::SizeType extractedRegionSize = inputSize;
+    typename InputImageType::RegionType extractedRegion;
+    extractedRegionSize[VImageDimension - 1] = 0;
+    extractedRegion.SetSize(extractedRegionSize);
+    start[VImageDimension - 1] = mSlice;
+    extractedRegion.SetIndex(start);
+
+    typename FilterType::Pointer filter = FilterType::New();
+    filter->SetExtractionRegion(extractedRegion);
+    filter->SetInput(reader->GetOutput());
+    filter->ReleaseDataFlagOn();
+    try {
+      filter->Update();
+    }
+    catch ( itk::ExceptionObject & err ) {
+      std::cerr << "Error while slicing " << mInputFilenames[0].c_str()
+                << "(slice #" << mSlice << ") " << err << std::endl;
+      return;
+    }
+    mImage->AddItkImage<SlicedImageType>(filter->GetOutput());
   } else {
     if (mInputFilenames.size() > 1) {
       typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
index 39a2d9a689c3eb0adb6a08a94d6ba6e5c3a14ac8..89a888456e6a37a38fb53c4efcd4ac5b638a2286 100644 (file)
@@ -234,6 +234,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionOpen_Dicom_Struct,SIGNAL(triggered()),this,SLOT(OpenDCStructContour()));
   connect(actionOpen_VTK_contour,SIGNAL(triggered()),this,SLOT(OpenVTKContour()));
   connect(actionOpen_Multiple_Images_As_One,SIGNAL(triggered()),this,SLOT(MergeImages()));
+  connect(actionSlice_Image_As_Multiple_Images,SIGNAL(triggered()),this,SLOT(SliceImages()));
   connect(actionOpen_Image_With_Time,SIGNAL(triggered()),this,SLOT(OpenImageWithTime()));
   connect(actionMerge_images_as_n_dim_t, SIGNAL(triggered()), this, SLOT(MergeImagesWithTime()));
   connect(actionSave_As,SIGNAL(triggered()),this,SLOT(SaveAs()));
@@ -301,6 +302,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
     QMenu * rmenu = new QMenu("Recently opened files...");
     rmenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
     menuFile->insertMenu(actionOpen_Image_With_Time,rmenu);
+    menuFile->insertSeparator(actionOpen_Image_With_Time);
     for (std::list<std::string>::iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
       QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")),
                                    (*i).c_str(),this);
@@ -594,6 +596,22 @@ void vvMainWindow::MergeImages()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::SliceImages()
+{
+  QString Extensions = EXTENSIONS;
+  Extensions += ";;All Files (*)";
+
+  QStringList files = QFileDialog::getOpenFileNames(this,tr("Slice Images"),mInputPathName,Extensions);
+  if (files.isEmpty())
+    return;
+  mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
+  std::vector<std::string> vector;
+  for (int i = 0; i < files.size(); i++)
+    vector.push_back(files[i].toStdString());
+  LoadImages(vector, SLICED);
+}
+//------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 void vvMainWindow::MergeImagesWithTime()
@@ -729,6 +747,32 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, LoadedImageType fi
   else
     fileSize = 1;
 
+  // For SLICED, we need the number of slices (ndim and #slices)
+  std::vector<unsigned int> nSlices;
+  nSlices.resize(files.size());
+  std::fill(nSlices.begin(), nSlices.end(), 1);
+  if (filetype == SLICED) {
+    for (int i = 0; i < fileSize; i++) {
+      itk::ImageIOBase::Pointer header = clitk::readImageHeader(files[i]);
+      QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+      if (!header) {
+        nSlices[i] = 0;
+        QString error = "Cannot open file \n";
+        error += files[i].c_str();
+        QMessageBox::information(this,tr("Reading problem"),error);
+        return;
+      }
+      if (header->GetNumberOfDimensions() < 3) {
+        nSlices[i] = 0;
+        QString error = "Dimension problem. Cannot slice \n";
+        error += files[i].c_str();
+        QMessageBox::information(this,tr("Reading problem"),error);
+        return;
+      }
+      nSlices[i] = header->GetDimensions( header->GetNumberOfDimensions()-1 );
+    }
+  }
+  
   //Only add to the list of recently opened files when a single file is opened,
   //to avoid polluting the list of recently opened files
   if (files.size() == 1) {
@@ -748,93 +792,95 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, LoadedImageType fi
     progress.SetProgress(i,fileSize);
     qApp->processEvents();
 
-    //read the image and put it in mSlicerManagers
-    vvSlicerManager* imageManager = new vvSlicerManager(4);
-    qApp->processEvents();
-
-    bool SetImageSucceed=false;
-
-    // Change filename if an image with the same already exist
-    int number = GetImageDuplicateFilenameNumber(files[i]);
-
-    if (filetype == IMAGE || filetype == IMAGEWITHTIME)
-      SetImageSucceed = imageManager->SetImage(files[i],filetype, number);
-    else {
-      SetImageSucceed = imageManager->SetImages(files,filetype, number);
-    }
-    if (SetImageSucceed == false) {
-      QApplication::restoreOverrideCursor();
-      QString error = "Cannot open file \n";
-      error += imageManager->GetLastError().c_str();
-      QMessageBox::information(this,tr("Reading problem"),error);
-      delete imageManager;
-    } else {
-      mSlicerManagers.push_back(imageManager);
-
-      //create an item in the tree with good settings
-      QTreeWidgetItem *item = new QTreeWidgetItem();
-      item->setData(0,Qt::UserRole,files[i].c_str());
-      QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
-      item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-      qApp->processEvents();
-
-      //Create the buttons for reload and close
+    for (int j = 0; j < nSlices[i]; j++) {
+      //read the image and put it in mSlicerManagers
+      vvSlicerManager* imageManager = new vvSlicerManager(4);
       qApp->processEvents();
-      QTreePushButton* cButton = new QTreePushButton;
-      cButton->setItem(item);
-      cButton->setColumn(COLUMN_CLOSE_IMAGE);
-      cButton->setToolTip(tr("close image"));
-      cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
-      connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-              this,SLOT(CloseImage(QTreeWidgetItem*, int)));
 
-      QTreePushButton* rButton = new QTreePushButton;
-      rButton->setItem(item);
-      rButton->setColumn(COLUMN_RELOAD_IMAGE);
-      rButton->setToolTip(tr("reload image"));
-      rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
-      connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
-              this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
+      bool SetImageSucceed=false;
 
-      DataTree->addTopLevelItem(item);
-      DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
-      DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+      // Change filename if an image with the same already exist
+      int number = GetImageDuplicateFilenameNumber(files[i] + std::string("_slice"));
 
-      //set the id of the image
-      QString id = files[i].c_str() + QString::number(mSlicerManagers.size()-1);
-      item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
-      mSlicerManagers.back()->SetId(id.toStdString());
-
-      linkPanel->addImage(imageManager->GetFileName(), id.toStdString());
-
-      connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
-              this,SLOT(CurrentImageChanged(std::string)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
-              this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
-              this, SLOT(VectorChanged(int,double,double,double, double)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)),
-              this, SLOT(OverlayChanged(int,double,double)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
-              this, SLOT(FusionChanged(int,double)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
-              this,SLOT(WindowsChanged(int, int, int)));
-      connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
-              this,SLOT(WindowLevelChanged(double, double, int, int)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
-              this,SLOT(UpdateSlice(int,int)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
-              this,SLOT(UpdateTSlice(int, int)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
-              this,SLOT(UpdateSliceRange(int,int,int,int,int)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
-              this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int)));
-      connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*)),
-              this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*)));
-      connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
-              this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
-      connect(mSlicerManagers.back(),SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
-      InitSlicers();
+      if (filetype == IMAGE || filetype == IMAGEWITHTIME || filetype == SLICED)
+        SetImageSucceed = imageManager->SetImage(files[i],filetype, number, j);
+      else {
+        SetImageSucceed = imageManager->SetImages(files,filetype, number);
+      }
+      if (SetImageSucceed == false) {
+        QApplication::restoreOverrideCursor();
+        QString error = "Cannot open file \n";
+        error += imageManager->GetLastError().c_str();
+        QMessageBox::information(this,tr("Reading problem"),error);
+        delete imageManager;
+      } else {
+        mSlicerManagers.push_back(imageManager);
+
+        //create an item in the tree with good settings
+        QTreeWidgetItem *item = new QTreeWidgetItem();
+        item->setData(0,Qt::UserRole,files[i].c_str());
+        QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
+        item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
+        qApp->processEvents();
+
+        //Create the buttons for reload and close
+        qApp->processEvents();
+        QTreePushButton* cButton = new QTreePushButton;
+        cButton->setItem(item);
+        cButton->setColumn(COLUMN_CLOSE_IMAGE);
+        cButton->setToolTip(tr("close image"));
+        cButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/exit.png")));
+        connect(cButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+                this,SLOT(CloseImage(QTreeWidgetItem*, int)));
+
+        QTreePushButton* rButton = new QTreePushButton;
+        rButton->setItem(item);
+        rButton->setColumn(COLUMN_RELOAD_IMAGE);
+        rButton->setToolTip(tr("reload image"));
+        rButton->setIcon(QIcon(QString::fromUtf8(":/common/icons/rotateright.png")));
+        connect(rButton,SIGNAL(clickedInto(QTreeWidgetItem*, int)),
+                this,SLOT(ReloadImage(QTreeWidgetItem*, int)));
+
+        DataTree->addTopLevelItem(item);
+        DataTree->setItemWidget(item, COLUMN_CLOSE_IMAGE, cButton);
+        DataTree->setItemWidget(item, COLUMN_RELOAD_IMAGE, rButton);
+
+        //set the id of the image
+        QString id = files[i].c_str() + QString::number(mSlicerManagers.size()-1);
+        item->setData(COLUMN_IMAGE_NAME,Qt::UserRole,id.toStdString().c_str());
+        mSlicerManagers.back()->SetId(id.toStdString());
+
+        linkPanel->addImage(imageManager->GetFileName(), id.toStdString());
+
+        connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
+                this,SLOT(CurrentImageChanged(std::string)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
+                this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
+                this, SLOT(VectorChanged(int,double,double,double, double)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateOverlay(int, double, double)),
+                this, SLOT(OverlayChanged(int,double,double)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
+                this, SLOT(FusionChanged(int,double)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
+                this,SLOT(WindowsChanged(int, int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
+                this,SLOT(WindowLevelChanged(double, double, int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
+                this,SLOT(UpdateSlice(int,int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
+                this,SLOT(UpdateTSlice(int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateSliceRange(int,int,int,int,int)),
+                this,SLOT(UpdateSliceRange(int,int,int,int,int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateLinkManager(std::string,int,double,double,double,int)),
+                this,SLOT(UpdateLinkManager(std::string,int,double,double,double,int)));
+        connect(mSlicerManagers.back(), SIGNAL(UpdateLinkedNavigation(std::string,vvSlicerManager*)),
+                this,SLOT(UpdateLinkedNavigation(std::string,vvSlicerManager*)));
+        connect(mSlicerManagers.back(), SIGNAL(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)),
+                this,SLOT(ChangeImageWithIndexOffset(vvSlicerManager*,int,int)));
+        connect(mSlicerManagers.back(),SIGNAL(LandmarkAdded()),landmarksPanel,SLOT(AddPoint()));
+        InitSlicers();
+      }
       numberofsuccesulreads++;
     }
   }
index 8f218a2a54f1f62b34c1882d9850eeb9eb70a919..c21939754107158077001f72023ccea754fc53a8 100644 (file)
@@ -72,6 +72,7 @@ public slots:
   void OpenRecentImage();
   void OpenImageWithTime();
   void MergeImages();
+  void SliceImages();
   void MergeImagesWithTime();
   void OpenDicom();
   ///Open a vtkPolyData surface mesh and display it over the current image
index 913ede73da2f92f3cfc351467ecf001399d12b66..46e7764228b8a2b659171fef71c158535e2bb96c 100644 (file)
@@ -146,7 +146,7 @@ void vvSlicerManager::ToggleContourSuperposition()
 
 
 //----------------------------------------------------------------------------
-bool vvSlicerManager::SetImage(std::string filename, LoadedImageType type, int n)
+bool vvSlicerManager::SetImage(std::string filename, LoadedImageType type, int n, unsigned int slice)
 {
   mType = type;
   if (mReader == NULL)
@@ -154,6 +154,7 @@ bool vvSlicerManager::SetImage(std::string filename, LoadedImageType type, int n
   std::vector<std::string> filenames;
   filenames.push_back(filename);
   mReader->SetInputFilenames(filenames);
+  mReader->SetSlice(slice); // Only used for SLICED type
   mReader->Update(type);
 
   SetFilename(filename, n);
index 431f1a04ef1b52f52efceb727eccac6a4f55911d..ed118f534f7357cc35e8c763704ce4b63d89bbd6 100644 (file)
@@ -58,7 +58,7 @@ class vvSlicerManager : public QObject {
     return mLastError;
   }
 
-  bool SetImage(std::string filename,LoadedImageType type, int n=0);
+  bool SetImage(std::string filename,LoadedImageType type, int n=0, unsigned int slice=0);
   void SetImage(vvImage::Pointer image);
   bool SetImages(std::vector<std::string> filenames, LoadedImageType type, int n=0);