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})
#if defined(unix) || defined(__APPLE__)
# include <sys/time.h>
# include <sys/resource.h>
-#elif defined(WIN32)
+#elif defined(_WIN32)
# include <windows.h>
#endif
#cmakedefine01 CLITK_EXPERIMENTAL
#cmakedefine01 CLITK_MEMORY_INFO
+#cmakedefine01 CLITK_PRIVATE_FEATURES
// Global environment variables
#define OS_NAME "@CMAKE_SYSTEM@"
#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; \
}
//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
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)
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+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)
{
}
//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
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()
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);
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;
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+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)
{
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);
#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
===========================================================================**/
#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
clitk::Timer::Timer()
{
Reset();
-#if defined(WIN32)
+#if defined(_WIN32)
QueryPerformanceFrequency((LARGE_INTEGER*)&mFrequency);
#endif
}
{
#if defined(unix) || defined(__APPLE__)
getrusage(RUSAGE_SELF, &mBegin);
-#elif defined(WIN32)
+#elif defined(_WIN32)
QueryPerformanceCounter((LARGE_INTEGER*)&mBegin);
#endif
mNumberOfCall++;
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;
#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>
#if defined(unix) || defined(__APPLE__)
rusage mBegin;
rusage mEnd;
-#elif defined(WIN32)
+#elif defined(_WIN32)
unsigned __int64 mBegin;
unsigned __int64 mEnd;
unsigned __int64 mFrequency;
#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
{
// 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);
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;
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;
}
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;
--- /dev/null
+<?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>
#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
///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();}
// 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>
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
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)));
mLabelInputInfo->setText(QString("%1").arg(m->GetFileName().c_str()));
// Auto display browser to select new contours
- if (mOpenFileBrowserFlag) OpenBinaryImage();
+ if (mOpenFileBrowserFlag) Open();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-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);
+
}
//------------------------------------------------------------------------------
{
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";
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();
//------------------------------------------------------------------------------
-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();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vvToolROIManager::ChangeContourWidth(int n) {
if (mCurrentROIActor == NULL) return;
- mCurrentROIActor->SetContourWidth(n);
- mCurrentROIActor->UpdateColor();
- mCurrentSlicerManager->Render();
+ mCurrentROIActor->SetContourWidth(n);
+ mCurrentROIActor->UpdateColor();
+ mCurrentSlicerManager->Render();
}
//------------------------------------------------------------------------------
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;
}
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);
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);
--- /dev/null
+/*=========================================================================
+ 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();
+}
+//------------------------------------------------------------------------------
--- /dev/null
+/*=========================================================================
+ 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