36 #include <ctkPluginContext.h>
48 #include <vtkImageImport.h>
49 #include <vtkImageData.h>
50 #include <vtkImageShiftScale.h>
51 #include <vtkImageData.h>
55 #include <itkBinaryMorphologicalClosingImageFilter.h>
56 #include <itkBinaryBallStructuringElement.h>
58 #include <vtkImageCast.h>
60 #include "levelSet.hpp"
61 #include "OpenCLManager.hpp"
62 #include "HelperFunctions.hpp"
66 #include "level-set-segmentation-config.h"
67 #include "OulConfig.hpp"
80 return "Level Set Segmentation";
85 return "LevelSetFilter";
91 "<h3>Level Set Segmentation Filter.</h3>"
98 Vector3D point = spaceProvider->getActiveToolTipPoint(
99 spaceProvider->getD(data));
103 double spacingX, spacingY, spacingZ;
105 point(0) = point(0) * (1.0 / spacingX);
106 point(1) = point(1) * (1.0 / spacingY);
107 point(2) = point(2) * (1.0 / spacingZ);
109 std::cout <<
"the selected seed point is: " << point(0) <<
" " << point(1)
110 <<
" " << point(2) <<
"\n";
117 ImagePtr image = boost::dynamic_pointer_cast<
Image>(inputImage);
124 std::cout <<
"size of image is: " << size[0] <<
" " << size[1] <<
" "
126 int x = (int) seedPoint(0);
127 int y = (int) seedPoint(1);
128 int z = (int) seedPoint(2);
129 bool result = x >= 0 && y >= 0 && z >= 0 && x < size[0] && y < size[1]
139 std::cout <<
"No input data selected" << std::endl;
143 if (inputImage->getType() !=
"image")
145 std::cout <<
"Input data has to be an image" << std::endl;
150 +
"/" + inputImage->getFilename()).toStdString();
155 std::cout <<
"Seed point is not inside image!" << std::endl;
171 std::cout <<
"Parameters are set to: " << threshold <<
" " << epsilon <<
" "
172 << alpha << std::endl;
175 SIPL::int3 seed(seedPoint(0), seedPoint(1), seedPoint(2));
181 SIPL::Volume<char> * result = runLevelSet(filename.c_str(), seed, 10,
183 threshold, epsilon, alpha, kernelDir.toStdString(), oulDir.toStdString());
184 SIPL::int3 size = result->getSize();
185 rawSegmentation = this->convertToVtkImageData(
186 (
char *) result->getData(), size.x, size.y, size.z, image);
190 }
catch (SIPL::SIPLException &e)
192 std::string error = e.what();
197 }
catch (cl::Error &e)
199 if (e.err() == CL_MEM_OBJECT_ALLOCATION_FAILURE
200 || e.err() == CL_OUT_OF_RESOURCES)
203 "cl::Error: Not enough memory on the device to process this image. ("
227 QString uidSegmentation = image->getUid() +
"_seg%1";
228 QString nameSegmentation = image->getName() +
"_seg%1";
232 outputSegmentation2->setVtkImageData(rawSegmentation);
236 if (!outputSegmentation2)
242 std::cout <<
"Performing morphological closing on segmentation result"
246 Eigen::Array3d spacing = image->getSpacing();
247 itk::Size<3> radiusInVoxels;
248 radiusInVoxels[0] = radius / spacing(0);
249 radiusInVoxels[1] = radius / spacing(1);
250 radiusInVoxels[2] = radius / spacing(2);
252 itkImageType::ConstPointer itkImage =
256 typedef itk::BinaryBallStructuringElement<unsigned char, 3> StructuringElementType;
257 StructuringElementType structuringElement;
258 structuringElement.SetRadius(radiusInVoxels);
259 structuringElement.CreateStructuringElement();
262 typedef itk::BinaryMorphologicalClosingImageFilter<
itkImageType,
263 itkImageType, StructuringElementType> closingFilterType;
264 closingFilterType::Pointer closingFilter = closingFilterType::New();
265 closingFilter->SetInput(itkImage);
266 closingFilter->SetKernel(structuringElement);
267 closingFilter->SetForegroundValue(1);
268 closingFilter->Update();
269 itkImage = closingFilter->GetOutput();
273 itkToVtkFilter->SetInput(itkImage);
274 itkToVtkFilter->Update();
277 rawResult->DeepCopy(itkToVtkFilter->GetOutput());
280 imageCast->SetInputData(rawResult);
281 imageCast->SetOutputScalarTypeToUnsignedChar();
282 rawResult = imageCast->GetOutput();
284 outputSegmentation =
patientService()->createSpecificData<
Image>(uidSegmentation, nameSegmentation);
286 outputSegmentation->setVtkImageData(rawResult);
287 rawSegmentation = rawResult;
291 outputSegmentation = outputSegmentation2;
295 double threshold = 1;
299 outputSegmentation->get_rMd_History()->setRegistration(rMd_i);
305 contour->get_rMd_History()->setRegistration(rMd_i);
308 mOutputTypes[0]->setValue(outputSegmentation->getUid());
332 temp->setValueName(
"Input");
333 temp->setHelp(
"Select image input for thresholding");
342 temp->setValueName(
"Output");
343 temp->setHelp(
"Output segmented binary image");
347 temp->setValueName(
"Contour");
348 temp->setHelp(
"Output contour generated from thresholded binary image.");
362 vtkImageDataPtr LevelSetFilter::convertToVtkImageData(
char * data,
int size_x,
363 int size_y,
int size_z,
ImagePtr input)
365 vtkImageDataPtr retval = this->importRawImageData((
void*) data, size_x,
366 size_y, size_z, input, VTK_UNSIGNED_CHAR);
385 vtkImageDataPtr LevelSetFilter::importRawImageData(
void * data,
int size_x,
386 int size_y,
int size_z,
ImagePtr input,
int type)
390 imageImport->SetWholeExtent(0, size_x - 1, 0, size_y - 1, 0, size_z - 1);
391 imageImport->SetDataExtentToWholeExtent();
392 imageImport->SetDataScalarType(type);
393 imageImport->SetNumberOfScalarComponents(1);
394 imageImport->SetDataSpacing(input->getBaseVtkImageData()->GetSpacing());
395 imageImport->SetImportVoidPointer(data);
396 imageImport->Update();
397 imageImport->Modified();
400 retval->DeepCopy(imageImport->GetOutput());
408 "Threshold",
"",
"Select threshold for the segmentation", 1,
417 "",
"Select epsilon for the segmentation", 1,
426 "",
"Select alpha for the segmentation", 0.1,
438 "Select radius (in mm) for the morphological closing of the final result. Radius at 0 will skip this process.",
DoublePropertyPtr getEpsilonOption(QDomElement root)
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
QString qstring_cast(const T &val)
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
void reportError(QString msg)
static bool isSeedPointInsideImage(Vector3D, DataPtr)
virtual void createInputTypes()
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService, QString typeRegexp=".*")
Utility class for describing a bounded numeric range.
boost::shared_ptr< class Image > ImagePtr
static Vector3D getSeedPointFromTool(SpaceProviderPtr spaceProvider, DataPtr image)
virtual bool postProcess()
virtual vtkImageDataPtr getBaseVtkImageData()
LevelSetFilter(ctkPluginContext *pluginContext)
virtual void setActive(bool on)
virtual QString getHelp() const
virtual void intitializeFromParentImage(ImagePtr parentImage)
std::vector< PropertyPtr > mOptionsAdapters
boost::shared_ptr< class Data > DataPtr
virtual void createOptions()
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
virtual void createOutputTypes()
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
PatientModelServicePtr patientService()
int * getImageSize(DataPtr inputImage)
SmartPointer< Self > Pointer
virtual void setActive(bool on)
DoublePropertyPtr getThresholdOption(QDomElement root)
vtkSmartPointer< class vtkImageCast > vtkImageCastPtr
cxLogicManager_EXPORT SpaceProviderPtr spaceProvider()
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
vtkSmartPointer< class vtkImageImport > vtkImageImportPtr
itk::Image< PixelType, Dimension > itkImageType
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
QDomElement getmOptions()
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
virtual bool postProcess()
static itkImageType::ConstPointer getITKfromSSCImage(ImagePtr image)
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
virtual QString getName() const
virtual QString getType() const
boost::shared_ptr< class Mesh > MeshPtr
DoublePropertyPtr getAlphaOption(QDomElement root)
DoublePropertyPtr getRadiusOption(QDomElement root)