]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
authorRomulo Pinho <romulo.pinho@lyon.unicancer.fr>
Thu, 30 Aug 2012 10:36:48 +0000 (12:36 +0200)
committerRomulo Pinho <romulo.pinho@lyon.unicancer.fr>
Thu, 30 Aug 2012 10:36:48 +0000 (12:36 +0200)
21 files changed:
common/CMakeLists.txt
common/clitkCommon.h
common/clitkConfiguration.h.in
common/clitkDD.h
common/clitkDicomRTStruct2ImageFilter.cxx
common/clitkDicomRTStruct2ImageFilter.h
common/clitkDicomRT_StructureSet.cxx
common/clitkDicomRT_StructureSet.h
common/clitkIO.cxx
common/clitkPortability.h
common/clitkTimer.cxx
common/clitkTimer.h
common/clitkXdrImageIOWriter.cxx
tools/clitkDicomRTStruct2Image.cxx
vv/qt_ui/vvToolSegmentation.ui [new file with mode: 0644]
vv/vvMainWindow.cxx
vv/vvStructSelector.h
vv/vvToolROIManager.cxx
vv/vvToolROIManager.h
vv/vvToolSegmentation.cxx [new file with mode: 0644]
vv/vvToolSegmentation.h [new file with mode: 0644]

index 336e22558c7e8628aa2b27e32550c3676c026182..4dcf32530b2d6ab661d0420b543f248d50de8ec1 100644 (file)
@@ -33,6 +33,12 @@ SET(clitkCommon_SRC
   vvImageReader.cxx
   vvImageWriter.cxx
 )
+IF(CLITK_PRIVATE_FEATURES)
+  SET(clitkCommon_SRC ${clitkCommon_SRC}
+    ${PROJECT_SOURCE_DIR}/private_features/clitkUsfImageIO.cxx
+    ${PROJECT_SOURCE_DIR}/private_features/clitkUsfImageIOFactory.cxx
+    )
+ENDIF(CLITK_PRIVATE_FEATURES)
 
 ### Declare clitkCommon library
 ADD_LIBRARY(clitkCommon STATIC ${clitkCommon_SRC})
index 769ca63f0bf4400cbb783cf53d3bd7b44b3fc293..9eb36522004c172b9cfa6d8bb209f45821cb02f5 100644 (file)
@@ -38,7 +38,7 @@
 #if defined(unix) || defined(__APPLE__)
 #  include <sys/time.h>
 #  include <sys/resource.h>
-#elif defined(WIN32)
+#elif defined(_WIN32)
 #  include <windows.h>
 #endif
 
index 5f99d7a9c7c27e3a83ac6e6b66999d24888e7a4d..8d1e1db7c10f7d793ea0accfbe34c856df69d3d4 100644 (file)
@@ -23,6 +23,7 @@
 
 #cmakedefine01 CLITK_EXPERIMENTAL
 #cmakedefine01 CLITK_MEMORY_INFO
+#cmakedefine01 CLITK_PRIVATE_FEATURES
 
 // Global environment variables
 #define OS_NAME "@CMAKE_SYSTEM@"
index c21bb815acbc080e97f3adfd9b844c934209292e..97ba4437b07e5f5207faf55bfee180ac63f1cd2b 100644 (file)
 #define clitkDD_h
 
 #include <iostream>
-#ifdef WIN32
+#ifdef _WIN32
 # include <windows.h>
 #endif
 // David's debug
 
-#ifdef WIN32
+#ifdef _WIN32
 # define DD(a) { \
     std::ostringstream ossDD; \
     ossDD << #a " = [ " << a << " ]" << std::endl; \
index 1541cb28f46f794e1ad274e12cb8c94c33bf9313..fa66cfb31361de6d96bea75d01676c0295901b67 100644 (file)
@@ -49,10 +49,22 @@ clitk::DicomRTStruct2ImageFilter::~DicomRTStruct2ImageFilter()
 }
 //--------------------------------------------------------------------
 
+
+//--------------------------------------------------------------------
 bool clitk::DicomRTStruct2ImageFilter::ImageInfoIsSet() const
 {
   return mSize.size() && mSpacing.size() && mOrigin.size();
 }
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRTStruct2ImageFilter::SetWriteOutputFlag(bool b)
+{
+  mWriteOutput = b;
+}
+//--------------------------------------------------------------------
+
 
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::SetROI(clitk::DicomRT_ROI * roi)
@@ -79,6 +91,25 @@ void clitk::DicomRTStruct2ImageFilter::SetOutputImageFilename(std::string s)
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+void clitk::DicomRTStruct2ImageFilter::SetImage(vvImage::Pointer image)
+{
+  if (image->GetNumberOfDimensions() != 3) {
+    std::cerr << "Error. Please provide a 3D image." << std::endl;
+    exit(0);
+  }
+  mSpacing.resize(3);
+  mOrigin.resize(3);
+  mSize.resize(3);
+  for(unsigned int i=0; i<3; i++) {
+    mSpacing[i] = image->GetSpacing()[i];
+    mOrigin[i] = image->GetOrigin()[i];
+    mSize[i] = image->GetSize()[i];
+  }
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
 {
@@ -101,20 +132,30 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
 }
 //--------------------------------------------------------------------
 
+
+//--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::SetOutputOrigin(const double* origin)
 {
   std::copy(origin,origin+3,std::back_inserter(mOrigin));
 }
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::SetOutputSpacing(const double* spacing)
 {
   std::copy(spacing,spacing+3,std::back_inserter(mSpacing));
 }
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::SetOutputSize(const unsigned long* size)
 {
   std::copy(size,size+3,std::back_inserter(mSize));
 }
+//--------------------------------------------------------------------
+
 
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::Update()
index 1add60e469c5ccab31a9221cb732d87f00348389..8f6045ae1e2b7100524464a6ee85c1faccde2a94 100644 (file)
@@ -37,6 +37,7 @@ namespace clitk {
 
     void SetROI(clitk::DicomRT_ROI * roi);
     ///This is used to create a mask with the same characteristics as an input image
+    void SetImage(vvImage::Pointer image);
     void SetImageFilename(std::string s);
     void SetOutputOrigin(const double* origin);
     void SetOutputSpacing(const double* spacing);
@@ -46,6 +47,7 @@ namespace clitk {
     vtkImageData * GetOutput();
     template <int Dimension> typename itk::Image<unsigned char,Dimension>::ConstPointer GetITKOutput();
     void SetCropMaskEnabled(bool b);
+    void SetWriteOutputFlag(bool b);
 
   protected:
     bool ImageInfoIsSet() const;
index 4ac4705ef73a673b0487980e569aac56ba3f01ef..a26804b1839a49f0a3d6e5c51693ccc09c98dead 100644 (file)
@@ -407,6 +407,49 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename)
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+bool clitk::DicomRT_StructureSet::IsDicomRTStruct(const std::string & filename)
+{
+  // Open DICOM
+#if GDCM_MAJOR_VERSION == 2
+  // Read gdcm file
+  mReader = new gdcm::Reader;
+  mReader->SetFileName(filename.c_str());
+  mReader->Read();
+  mFile = &(mReader->GetFile());
+  const gdcm::DataSet & ds = mFile->GetDataSet();
+  
+  // Check file type
+  //Verify if the file is a RT-Structure-Set dicom file
+  gdcm::MediaStorage ms;
+  ms.SetFromFile(*mFile);
+  if( ms != gdcm::MediaStorage::RTStructureSetStorage ) return false;
+
+  gdcm::Attribute<0x8,0x60> modality;
+  modality.SetFromDataSet( ds );
+  if( modality.GetValue() != "RTSTRUCT" ) return false;
+  
+  return true;
+
+  //----------------------------------------------------------------------------------------
+#else
+  mFile = new gdcm::File;
+  mFile->SetFileName(filename.c_str());
+  mFile->SetMaxSizeLoadEntry(16384); // Needed ...
+  mFile->SetLoadMode(gdcm::LD_NOSHADOW); // don't load shadow tags (in order to save memory)
+  mFile->Load();
+  
+  // Check file type
+  //Verify if the file is a RT-Structure-Set dicom file
+  if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0016),"1.2.840.10008.5.1.4.1.1.481.3")) 
+    return false;
+  if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0060),"RTSTRUCT")) return false;
+
+#endif
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 int clitk::DicomRT_StructureSet::AddBinaryImageAsNewROI(vvImage * im, std::string n)
 {
index d1cc37c2364b3451f9ad0b495b9de409a80c3425..5761e14dc28e167bf13ae0d3e92b68c5b448cc12 100644 (file)
@@ -49,6 +49,7 @@ public:
 
   void Print(std::ostream & os = std::cout) const;
   void Read(const std::string & filename);
+  bool IsDicomRTStruct(const std::string & filename);
   void Write(const std::string & filename);
 
   clitk::DicomRT_ROI * GetROIFromROINumber(int n);
index 1acd352808ba3ff8f01a8beaa6cd0e2db2ddc66e..011147d868fedb67d05b17cd3ec5ac15ec1b6135 100644 (file)
 #include "clitkXdrImageIOFactory.h"
 #include "clitkHndImageIOFactory.h"
 #include "clitkGateAsciiImageIOFactory.h"
+#include "clitkConfiguration.h"
+#if CLITK_PRIVATE_FEATURES
+  #include "clitkUsfImageIOFactory.h"
+#endif
 
 //--------------------------------------------------------------------
 // Register factories
 void clitk::RegisterClitkFactories()
 {
+#if CLITK_PRIVATE_FEATURES
+  clitk::UsfImageIOFactory::RegisterOneFactory();
+#endif
   clitk::GateAsciiImageIOFactory::RegisterOneFactory();
   clitk::DicomRTDoseIOFactory::RegisterOneFactory();
 #if ITK_VERSION_MAJOR <= 3
index 7fae01ec9916e31e303465a95685e7fa46d9b0db..3671066fce427e26fb789cb3311865b8c1e32287 100644 (file)
 ===========================================================================**/
 #ifndef CLITKPORTABILITY_H
 #define CLITKPORTABILITY_H
-#if defined(WIN32)
+#if defined(_WIN32)
 #  define _USE_MATH_DEFINES //Before math.h include (i.e. cmath)
 #endif
 #include <cmath>
 
-#if defined(WIN32)
+#if defined(_WIN32)
 #  define rint(x)  floor(x+0.5)
 #  define lrint(x) (long)rint(x) 
 #endif
index f01d77c1426d9ca45d35f4fdf0ca790832f5ef29..cd74428832f4505df7edd11028b359030ab064c5 100644 (file)
@@ -37,7 +37,7 @@
 clitk::Timer::Timer()
 {
   Reset();
-#if defined(WIN32)
+#if defined(_WIN32)
   QueryPerformanceFrequency((LARGE_INTEGER*)&mFrequency);
 #endif
 }
@@ -48,7 +48,7 @@ void clitk::Timer::Start()
 {
 #if defined(unix) || defined(__APPLE__)
   getrusage(RUSAGE_SELF, &mBegin);
-#elif defined(WIN32)
+#elif defined(_WIN32)
   QueryPerformanceCounter((LARGE_INTEGER*)&mBegin);
 #endif
   mNumberOfCall++;
@@ -64,7 +64,7 @@ void clitk::Timer::Stop(bool accumulate)
     mElapsed += (mEnd.ru_utime.tv_usec - mBegin.ru_utime.tv_usec)+
                 (mEnd.ru_utime.tv_sec - mBegin.ru_utime.tv_sec)*1000000;
   }
-#elif defined(WIN32)
+#elif defined(_WIN32)
   QueryPerformanceCounter((LARGE_INTEGER*)&mEnd);
   if (accumulate) {
     mElapsed += ((mEnd-mBegin)*1000000)/(long double)mFrequency;
index 0021fa75afc9b812e7e31c59fe92afb0e84f3c91..725a3b2bd506dbce7b2c7e1bfbb8de70e99da37f 100644 (file)
@@ -23,7 +23,7 @@
 #if defined(unix) || defined(__APPLE__)
 #  include <sys/time.h>
 #  include <sys/resource.h>
-#elif defined(WIN32)
+#elif defined(_WIN32)
 #  include <windows.h>
 #endif
 #include <iostream>
@@ -53,7 +53,7 @@ namespace clitk {
 #if defined(unix) || defined(__APPLE__)
     rusage mBegin; 
     rusage mEnd;
-#elif defined(WIN32)
+#elif defined(_WIN32)
     unsigned __int64 mBegin;
     unsigned __int64 mEnd;
     unsigned __int64 mFrequency;
index af50b0ea0dfe3399c3eec82424f810c1dc2f9e5f..fc75976b7feff9dfd92ed58e2f6008b1a0d7d709 100644 (file)
@@ -108,7 +108,7 @@ void clitk::XdrImageIO::Write(const void* buffer)
 
 #include <algorithm>
 
-#ifdef WIN32
+#ifdef _WIN32
 // don't use min() and max() macros indirectly defined by windows.h,
 // but use portable std::min() and std:max() instead
 #ifndef NOMINMAX
@@ -256,7 +256,7 @@ static int wxdr_write(int handle, const void * buf, unsigned len)
 {
   // if (handle == 1) // stdout
   if (handle == fileno(stdout)) {
-#ifdef WIN32
+#ifdef _WIN32
     // Behave as C standard library write(): return number of bytes
     // written or -1 and errno set on error.
     fflush(stdout);
@@ -837,6 +837,12 @@ void clitk::XdrImageIO::WriteImage(const char* file, char* headerinfo, char* hea
   char     *buf2;
   size_t   slen;
 
+#ifdef _WIN32
+  int oldFMode;
+  _get_fmode(&oldFMode);
+  _set_fmode(O_BINARY); /* default binary i/o */
+#endif
+
   if (bLittleEndian)
     swap_test = 0x00000001;
 
@@ -1203,5 +1209,10 @@ WRITE_COORDS:
     if (f != fileno(stdout)) close(f);
 
   if (getsize) return;
+
+#ifdef _WIN32
+  _set_fmode(oldFMode ? oldFMode : _O_TEXT); /* restore default binary i/o */
+#endif
+
   return AVS_OK;
 }
index cc231260f29c57287738efb1b3fee641884f0afe..88d480d1f625d9016beff80ec72e256191a22efd 100644 (file)
@@ -41,7 +41,7 @@ int main(int argc, char * argv[]) {
   if (args_info.roi_arg != -1) {
     filter.SetROI(s->GetROIFromROINumber(args_info.roi_arg)); 
     filter.SetOutputImageFilename(args_info.output_arg);
-  filter.Update();  
+    filter.Update();  
   }
   else {
     clitk::DicomRT_StructureSet::ROIConstIteratorType iter;
diff --git a/vv/qt_ui/vvToolSegmentation.ui b/vv/qt_ui/vvToolSegmentation.ui
new file mode 100644 (file)
index 0000000..4931841
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>vvToolSegmentation</class>
+ <widget class="QWidget" name="vvToolSegmentation">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>408</width>
+    <height>285</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Binarize image</string>
+  </property>
+  <widget class="QPushButton" name="pushButton">
+   <property name="geometry">
+    <rect>
+     <x>140</x>
+     <y>120</y>
+     <width>86</width>
+     <height>27</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>PushButton</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 46b0ecbb2fd9f2bb1a7656876978d531c734631c..9fc078cb1c09dbcdd362e17cda4fbdb5b6f75eeb 100644 (file)
 #define COLUMN_RELOAD_IMAGE 6
 #define COLUMN_IMAGE_NAME 7
 
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr)"
+#if CLITK_PRIVATE_FEATURES
+  #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr *.usf)"
+#else
+  #define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN *.nii *.nrrd *.nhdr)"
+#endif
 
 /*Data Tree values
   0,Qt::UserRole full filename
index 2fe899b6f27368920b66925517122491876165b8..b6478771bc0a2f612bb7b2830339e4a3c0b1d6d9 100644 (file)
@@ -33,6 +33,9 @@ public:
     ///Enables the propagation checkbox
     void EnablePropagationCheckBox() {this->propagateCheckBox->setEnabled(true);
         this->propagateCheckBox->setChecked(true);}
+    void SetPropagationCheckBoxFlag(bool b) {
+      this->propagateCheckBox->setEnabled(b);
+      this->propagateCheckBox->setChecked(b);}
     ///Returns true if contours should be propagated over the sequence using the vf
     bool PropagationEnabled() {return this->propagateCheckBox->isChecked();}
 
index 738274667a43126eec48d244b2e51114b952ebd1..8b0a48753671fc735e6cfed736dae8d62bfda1d1 100644 (file)
 // vv
 #include "vvToolROIManager.h"
 #include "vvImageReader.h"
+#include "vvImageWriter.h"
 #include "vvROIActor.h"
 #include "vvSlicer.h"
 #include "vvROIActor.h"
 #include "vvMeshReader.h"
 #include "vvStructSelector.h"
 #include "vvToolManager.h"
+#include "vvProgressDialog.h"
+
+// clitk
+#include "clitkDicomRTStruct2ImageFilter.h"
+#include "clitkDicomRT_StructureSet.h"
 
 // Qt
 #include <QFileDialog>
@@ -62,7 +68,7 @@ vvToolROIManager::vvToolROIManager(vvMainWindowBase * parent, Qt::WindowFlags f)
   mTree->header()->resizeSection(0, 30);
   mGroupBoxROI->setEnabled(false);
   
-  // Temporary disable "Load dicom" button
+  // Disable "Load dicom" button -> not useful
   frame_4->hide();
 
   // Set default LUT
@@ -195,8 +201,8 @@ void  vvToolROIManager::InitializeNewTool(bool ReadStateFlag)
           this, SLOT(AnImageIsBeingClosed(vvSlicerManager *)));
   connect(mMainWindow, SIGNAL(SelectedImageHasChanged(vvSlicerManager *)), 
           this, SLOT(SelectedImageHasChanged(vvSlicerManager *)));
-  connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(OpenBinaryImage()));
-  connect(mOpenDicomButton, SIGNAL(clicked()), this, SLOT(OpenDicomImage()));
+  connect(mOpenBinaryButton, SIGNAL(clicked()), this, SLOT(Open()));
+  //  connect(mOpenDicomButton, SIGNAL(clicked()), this, SLOT(OpenDicomImage()));
   connect(mTree, SIGNAL(itemSelectionChanged()), this, SLOT(SelectedItemChangedInTree()));
   connect(mCheckBoxShow, SIGNAL(toggled(bool)), this, SLOT(VisibleROIToggled(bool)));
   connect(mOpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityChanged(int)));
@@ -231,7 +237,7 @@ void vvToolROIManager::InputIsSelected(vvSlicerManager *m)
   mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
 
   // Auto display browser to select new contours 
-  if (mOpenFileBrowserFlag) OpenBinaryImage();
+  if (mOpenFileBrowserFlag) Open();
 }
 //------------------------------------------------------------------------------
 
@@ -287,15 +293,22 @@ void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m) {
 
 
 //------------------------------------------------------------------------------
-void vvToolROIManager::OpenBinaryImage() 
+void vvToolROIManager::Open() 
 {
   // Open images
-  QString Extensions = "Images files ( *.mha *.mhd *.hdr *.his)";
+  QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
   Extensions += ";;All Files (*)";
   QStringList filename =
-    QFileDialog::getOpenFileNames(this,tr("Open binary image"),
+    QFileDialog::getOpenFileNames(this,tr("Open binary image or DICOM RT Struct"),
                                  mMainWindowBase->GetInputPathName(),Extensions);
-  OpenBinaryImage(filename);
+  if (filename.size() == 0) return;
+  if (filename.size() > 1) { OpenBinaryImage(filename); return; }
+
+  // Try to read dicom rt ?
+  clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
+  if (s->IsDicomRTStruct(filename[0].toStdString())) OpenDicomImage(filename[0].toStdString());
+  else OpenBinaryImage(filename);
+
 }
 //------------------------------------------------------------------------------
 
@@ -305,17 +318,21 @@ void vvToolROIManager::OpenBinaryImage(QStringList & filename)
 {
   if (filename.size() == 0) return;
   
+  vvProgressDialog p("Reading ROI ...", true);
+  p.SetCancelButtonEnabled(false);
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  
   // For each selected file, open the image
-  for(int i=0; i<filename.size(); i++) {
+  for(int i=0; i<filename.size(); i++) { 
+    p.SetProgress(i, filename.size());
+
     // Open Image
-    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     vvImageReader::Pointer reader = vvImageReader::New();
     std::vector<std::string> filenames;
     filenames.push_back(filename[i].toStdString());
     reader->SetInputFilenames(filenames);
     reader->Update(vvImageReader::IMAGE);
-    QApplication::restoreOverrideCursor();
-
+  
     if (reader->GetLastError().size() != 0) {
       std::cerr << "Error while reading " << filename[i].toStdString() << std::endl;
       QString error = "Cannot open file \n";
@@ -326,10 +343,9 @@ void vvToolROIManager::OpenBinaryImage(QStringList & filename)
     vvImage::Pointer binaryImage = reader->GetOutput();
     AddImage(binaryImage, filename[i].toStdString(), mBackgroundValueSpinBox->value(),
              (!mBGModeCheckBox->isChecked()));
-    //    mOpenedBinaryImage.push_back(binaryImage);
     mOpenedBinaryImageFilenames.push_back(filename[i]);
-    //mMapImageToIndex[binaryImage]=mOpenedBinaryImageFilenames.size()-1;
   }
+  QApplication::restoreOverrideCursor();
 
   // Update the contours
   UpdateAllContours(); 
@@ -338,40 +354,49 @@ void vvToolROIManager::OpenBinaryImage(QStringList & filename)
 
 
 //------------------------------------------------------------------------------
-void vvToolROIManager::OpenDicomImage() 
+void vvToolROIManager::OpenDicomImage(std::string filename
 {
-  DD("OpenDicomImage");
-  QString Extensions = "Dicom Files ( *.dcm RS*)";
-  Extensions += ";;All Files (*)";
-  QString file = QFileDialog::getOpenFileName(this,tr("Merge Images"), 
-                                              mMainWindow->GetInputPathName(), 
-                                              Extensions);
-  if (file.isNull()) return;
-
-  //  AddDCStructContour(index, file);
+  // GUI selector of roi
   vvMeshReader reader;
-  reader.SetFilename(file.toStdString());
+  reader.SetFilename(filename);
   vvStructSelector selector;
   selector.SetStructures(reader.GetROINames());
-  // selector.EnablePropagationCheckBox(); FIXME Disable
+  selector.SetPropagationCheckBoxFlag(false);
+  
+  if (selector.exec()) { 
+    vvProgressDialog p("Reading ROI...", true);
+    p.SetCancelButtonEnabled(false);
+    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
-  // FIXME : change text -> allow to save binary image
+    // Read information
+    clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
+    s->Read(filename);
+
+    // Loop on selected struct
+    std::vector<int> list = selector.getSelectedItems();
+    for (uint i=0; i<list.size(); i++) {
+      p.SetProgress(i, list.size());
+      
+      clitk::DicomRTStruct2ImageFilter filter;
+      filter.SetCropMaskEnabled(true);
+      filter.SetImage(mCurrentImage);
+      filter.SetROI(s->GetROIFromROINumber(list[i])); 
+      filter.SetWriteOutputFlag(false);
+      filter.Update();  
+
+      // Get image
+      vvImage::Pointer binaryImage = vvImage::New();
+      binaryImage->AddVtkImage(filter.GetOutput());
+    
+      // Add to gui
+      AddImage(binaryImage, s->GetROIFromROINumber(list[i])->GetName(), 0, true);
+      mOpenedBinaryImageFilenames.push_back(filename.c_str());
+    }
 
-  if (selector.exec()) {
-    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-    reader.SetSelectedItems(selector.getSelectedItems());
-    reader.SetImage(mCurrentSlicerManager->GetImage());
-    reader.Update();
-
-    // std::vector<vvMesh::Pointer> contours=reader.GetOutput();
-    // for (std::vector<vvMesh::Pointer>::iterator i=contours.begin();
-    //      i!=contours.end(); i++)
-    //   AddContour(index,*i,selector.PropagationEnabled());
     QApplication::restoreOverrideCursor();
   }
-
-
-
+  // Update the contours
+  UpdateAllContours(); 
 }
 //------------------------------------------------------------------------------
 
@@ -689,9 +714,9 @@ void vvToolROIManager::ChangeContourColor() {
 //------------------------------------------------------------------------------
 void vvToolROIManager::ChangeContourWidth(int n) {
   if (mCurrentROIActor == NULL) return;
-    mCurrentROIActor->SetContourWidth(n);
-    mCurrentROIActor->UpdateColor();
-    mCurrentSlicerManager->Render();
+  mCurrentROIActor->SetContourWidth(n);
+  mCurrentROIActor->UpdateColor();
+  mCurrentSlicerManager->Render();
 }
 //------------------------------------------------------------------------------
 
@@ -724,8 +749,9 @@ void vvToolROIManager::ReloadCurrentROI() {
   reader->SetInputFilename(mCurrentROI->GetFilename());
   reader->Update(vvImageReader::IMAGE);
   if (reader->GetLastError() != "") {
-    QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"), 
-                             reader->GetLastError().c_str());
+    // No message just ignore (because can be from dicom)
+    // QMessageBox::information(mMainWindowBase, tr("Sorry, error. Could not reload"), 
+    //                          reader->GetLastError().c_str());
     return;
   }
 
@@ -842,32 +868,32 @@ void vvToolROIManager::ReadXMLInformation_ROI()
     if (value == "Overlay" && m_XmlReader->isStartElement()) {
       QXmlStreamAttributes attributes = m_XmlReader->attributes();
       if (!m_XmlReader->hasError())
-         r = attributes.value("Red").toString().toFloat();
+        r = attributes.value("Red").toString().toFloat();
+      if (!m_XmlReader->hasError())
+        g = attributes.value("Green").toString().toFloat();
       if (!m_XmlReader->hasError())
-         g = attributes.value("Green").toString().toFloat();
+        b = attributes.value("Blue").toString().toFloat();
       if (!m_XmlReader->hasError())
-         b = attributes.value("Blue").toString().toFloat();
+        visible = attributes.value("Visible").toString().toInt();
       if (!m_XmlReader->hasError())
-         visible = attributes.value("Visible").toString().toInt();
+        opacity = attributes.value("Opacity").toString().toFloat();
       if (!m_XmlReader->hasError())
-         opacity = attributes.value("Opacity").toString().toFloat();
-     if (!m_XmlReader->hasError())
-         depth = attributes.value("Depth").toString().toFloat();
+        depth = attributes.value("Depth").toString().toFloat();
     }
 
 
     if (value == "Contour" && m_XmlReader->isStartElement()) {
       QXmlStreamAttributes attributes = m_XmlReader->attributes();
       if (!m_XmlReader->hasError())
-         cr = attributes.value("Red").toString().toFloat();
+        cr = attributes.value("Red").toString().toFloat();
       if (!m_XmlReader->hasError())
-         cg = attributes.value("Green").toString().toFloat();
+        cg = attributes.value("Green").toString().toFloat();
       if (!m_XmlReader->hasError())
-         cb = attributes.value("Blue").toString().toFloat();
+        cb = attributes.value("Blue").toString().toFloat();
       if (!m_XmlReader->hasError())
-         cvisible = attributes.value("Visible").toString().toInt();
+        cvisible = attributes.value("Visible").toString().toInt();
       if (!m_XmlReader->hasError())
-         width = attributes.value("Width").toString().toFloat();
+        width = attributes.value("Width").toString().toFloat();
     }
     param->SetOverlayColor(r,g,b);
     param->SetVisible(visible);
index 1f0f81ccf87b2be0471aa52a2bc477f03cf37353..03cbff9a3242fdc3dba1d00c1360f924c696f142 100644 (file)
@@ -52,9 +52,9 @@ class vvToolROIManager:
   public slots:
   void AnImageIsBeingClosed(vvSlicerManager *);
   void SelectedImageHasChanged(vvSlicerManager *);
-  void OpenBinaryImage();
+  void Open();
   void OpenBinaryImage(QStringList & filenames);
-  void OpenDicomImage();
+  void OpenDicomImage(std::string filaneme);
   void SelectedItemChangedInTree();
   void VisibleROIToggled(bool b);
   void VisibleContourROIToggled(bool b);
diff --git a/vv/vvToolSegmentation.cxx b/vv/vvToolSegmentation.cxx
new file mode 100644 (file)
index 0000000..dea3513
--- /dev/null
@@ -0,0 +1,254 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+// vv
+#include "vvToolSegmentation.h"
+#include "vvSlicerManager.h"
+#include "vvSlicer.h"
+#include "vvToolInputSelectorWidget.h"
+#include "vvImageWriter.h"
+
+// Qt
+#include <QFileDialog>
+#include <QMessageBox>
+
+// vtk
+#include "vtkImageContinuousErode3D.h"
+#include "vtkImageContinuousDilate3D.h"
+//------------------------------------------------------------------------------
+// Create the tool and automagically (I like this word) insert it in
+// the main window menu.
+ADD_TOOL(vvToolSegmentation);
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::Initialize()
+{
+  SetToolName("Segmentation");
+  SetToolMenuName("Interactive Segmentation");
+  SetToolIconFilename(":/common/icons/ducky.ico");
+  SetToolTip("Image interactive segmentation (trial).");
+  SetToolExperimental(true);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+vvToolSegmentation::vvToolSegmentation(vvMainWindowBase * parent, Qt::WindowFlags f)
+  :vvToolWidgetBase(parent,f),
+   vvToolBase<vvToolSegmentation>(parent),
+   Ui::vvToolSegmentation()
+{
+  // GUI Initialization
+  Ui_vvToolSegmentation::setupUi(mToolWidget);
+  setAttribute(Qt::WA_DeleteOnClose);
+
+  // Set how many inputs are needed for this tool
+  AddInputSelector("Select one image");
+  
+  // Init
+  mKernelValue = 3; // FIXME must be odd. If even -> not symmetrical
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+vvToolSegmentation::~vvToolSegmentation()
+{
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+bool vvToolSegmentation::close()
+{
+  mRefMaskActor->RemoveActors();
+  QWidget::close();  
+  mCurrentSlicerManager->Render();
+  return true;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::InputIsSelected(vvSlicerManager * m)
+{
+  DD("InputIsSelected");
+  mCurrentSlicerManager = m;
+  mCurrentImage = mCurrentSlicerManager->GetImage();
+
+  // Refuse if non 3D image
+  if (mCurrentImage->GetNumberOfDimensions() != 3) {
+    QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
+    close();
+    return;
+  }
+
+  // Change gui
+  //mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
+
+  // Open mask
+  OpenBinaryImage();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::apply()
+{
+  DD("apply");
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::OpenBinaryImage()
+{
+  DD("OpenBinaryImage");
+
+  // Load browser and select image
+  QString Extensions = "Images files ( *.mha *.mhd *.hdr *.his)";
+  Extensions += ";;All Files (*)";
+  QString filename =
+    QFileDialog::getOpenFileName(this,tr("Open binary image"),
+                                 mMainWindowBase->GetInputPathName(),Extensions);
+  DD(filename.toStdString());
+  if (filename.size() == 0) return;
+  
+  // Open Image
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  vvImageReader::Pointer reader = vvImageReader::New();
+  std::vector<std::string> filenames;
+  filenames.push_back(filename.toStdString());
+  reader->SetInputFilenames(filenames);
+  reader->Update(vvImageReader::IMAGE);
+  QApplication::restoreOverrideCursor();
+  
+  if (reader->GetLastError().size() != 0) {
+    std::cerr << "Error while reading " << filename.toStdString() << std::endl;
+    QString error = "Cannot open file \n";
+    error += reader->GetLastError().c_str();
+    QMessageBox::information(this,tr("Reading problem"),error);
+    return;
+  }
+
+  mMaskImage = reader->GetOutput();
+  int dim = mMaskImage->GetNumberOfDimensions();
+  if (dim != 3 ) {
+    QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
+    close();
+    return;
+  }
+
+  // Add a new roi actor
+  mRefMaskActor = QSharedPointer<vvROIActor>(new vvROIActor);
+  std::vector<double> color;
+  color.push_back(1);
+  color.push_back(0);
+  color.push_back(0);
+  clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
+  roi->SetFromBinaryImage(mMaskImage, 1, std::string("toto"), color, filename.toStdString());
+  mRefMaskActor->SetBGMode(true);
+  mRefMaskActor->SetROI(roi);
+  mRefMaskActor->SetSlicerManager(mCurrentSlicerManager);
+  mRefMaskActor->Initialize(10, true);
+  mRefMaskActor->Update();
+
+  // Prepare widget to get keyboard event
+  grabKeyboard();
+  //connect(this, SIGNAL(keyPressEvent(QKeyEvent*)), this, SLOT(keyPressed(QKeyEvent*)));
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::keyPressEvent(QKeyEvent * event)
+{
+  vvToolWidgetBase::keyPressEvent(event);
+  //DD("key");
+  
+  if (event->text() == "e") {
+    Erode();
+  }
+  if (event->text() == "d") {
+    Dilate(); // FIXME -> extend image BB !!
+  }
+  if (event->text() == "s") {
+    vvImageWriter::Pointer writer = vvImageWriter::New();
+    writer->SetOutputFileName("a.mha");
+    writer->SetInput(mMaskImage);
+    writer->Update();
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::Erode()
+{
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  vtkImageContinuousErode3D* erode = vtkImageContinuousErode3D::New();
+  erode->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
+  vtkImageData* image = mMaskImage->GetVTKImages()[0];
+  erode->SetInput(image);
+  erode->Update();
+  image->DeepCopy(erode->GetOutput());
+  image->Update();
+  UpdateAndRender();
+  erode->Delete();
+  QApplication::restoreOverrideCursor();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::Dilate()
+{
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  vtkImageContinuousDilate3D* dilate = vtkImageContinuousDilate3D::New();
+  dilate->SetKernelSize(mKernelValue,mKernelValue,mKernelValue);
+  vtkImageData* image = mMaskImage->GetVTKImages()[0];
+  dilate->SetInput(image);
+  dilate->Update();
+  image->DeepCopy(dilate->GetOutput());
+  image->Update();
+  UpdateAndRender();
+  dilate->Delete();
+  QApplication::restoreOverrideCursor();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::UpdateAndRender()
+{
+  bool visible = mRefMaskActor->IsVisible();
+  bool cvisible = mRefMaskActor->IsContourVisible();
+  mRefMaskActor->SetVisible(false);
+  mRefMaskActor->SetContourVisible(false);
+  mCurrentSlicerManager->Render();
+
+  //mRefMaskActor->RemoveActors();
+  mRefMaskActor->UpdateImage();
+  mRefMaskActor->SetVisible(visible);
+  mRefMaskActor->SetContourVisible(cvisible);
+  mCurrentSlicerManager->Render();
+}
+//------------------------------------------------------------------------------
diff --git a/vv/vvToolSegmentation.h b/vv/vvToolSegmentation.h
new file mode 100644 (file)
index 0000000..7b8bb8c
--- /dev/null
@@ -0,0 +1,64 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef VVTOOLSEGMENTATION_H
+#define VVTOOLSEGMENTATION_H
+
+#include <QtDesigner/QDesignerExportWidget>
+
+#include "vvToolBase.h"
+#include "vvToolWidgetBase.h"
+#include "vvROIActor.h"
+#include "ui_vvToolSegmentation.h"
+
+//------------------------------------------------------------------------------
+class vvToolSegmentation:
+  public vvToolWidgetBase,
+  public vvToolBase<vvToolSegmentation>, 
+  private Ui::vvToolSegmentation 
+{
+  Q_OBJECT
+    public:
+  vvToolSegmentation(vvMainWindowBase * parent=0, Qt::WindowFlags f=0);
+  ~vvToolSegmentation();
+
+  //-----------------------------------------------------
+  static void Initialize();
+  virtual void InputIsSelected(vvSlicerManager * m);
+  void OpenBinaryImage();
+  void Erode();
+  void Dilate();
+  void UpdateAndRender();
+
+  //-----------------------------------------------------
+  public slots:
+  virtual void apply();
+  virtual void keyPressEvent(QKeyEvent * event);
+  virtual bool close();
+  // virtual void reject();
+
+ protected:
+  // virtual void closeEvent(QCloseEvent *event);
+  Ui::vvToolSegmentation ui;
+  QSharedPointer<vvROIActor> mRefMaskActor;
+  vvImage::Pointer mMaskImage;
+  int mKernelValue;
+
+}; // end class vvToolSegmentation
+//------------------------------------------------------------------------------
+
+#endif