Пример #1
0
void meVTKSkeleton::ComputeAssociatedAverageOutwardFlux()
{
	//To have a good quality gradient of the distance map, perform a light smooth over it. Define  
	//convolution kernels in each direction and use them recursively. 
	typedef itk::RecursiveGaussianImageFilter< SkeletonAPITypes::InputImageType , SkeletonAPITypes::InputImageType > RecursiveGaussianFilterType;
	RecursiveGaussianFilterType::Pointer gaussianFilterX = RecursiveGaussianFilterType::New();
	RecursiveGaussianFilterType::Pointer gaussianFilterY = RecursiveGaussianFilterType::New();
	RecursiveGaussianFilterType::Pointer gaussianFilterZ = RecursiveGaussianFilterType::New();

	gaussianFilterX->SetDirection( 0 );
	gaussianFilterY->SetDirection( 1 );
	gaussianFilterZ->SetDirection( 2 );

	gaussianFilterX->SetOrder( RecursiveGaussianFilterType::ZeroOrder );
	gaussianFilterY->SetOrder( RecursiveGaussianFilterType::ZeroOrder );
	gaussianFilterZ->SetOrder( RecursiveGaussianFilterType::ZeroOrder );

	gaussianFilterX->SetNormalizeAcrossScale( false );
	gaussianFilterY->SetNormalizeAcrossScale( false );
	gaussianFilterZ->SetNormalizeAcrossScale( false );

	gaussianFilterX->SetInput( this->inputData );
	gaussianFilterY->SetInput( gaussianFilterX->GetOutput() );
	gaussianFilterZ->SetInput( gaussianFilterY->GetOutput() );

	gaussianFilterX->SetSigma( this->sigma );
	gaussianFilterY->SetSigma( this->sigma );
	gaussianFilterZ->SetSigma( this->sigma );

	typedef itk::GradientImageFilter< SkeletonAPITypes::InputImageType , SkeletonAPITypes::InputPixelType, SkeletonAPITypes::InputPixelType > GradientFilterType;
	typedef GradientFilterType::OutputImageType::PixelType GradientPixelType;
	// Compute the gradient.
	GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
	gradientFilter->SetInput( gaussianFilterZ->GetOutput() );

	// Compute the average outward flux.
	typedef itk::AverageOutwardFluxImageFilter< SkeletonAPITypes::InputImageType, SkeletonAPITypes::InputPixelType, GradientPixelType > AOFFilterType;
	AOFFilterType::Pointer aofFilter = AOFFilterType::New();
	aofFilter->SetInput( this->inputData );
	aofFilter->SetGradientImage( gradientFilter->GetOutput() );

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 2. Compute the skeleton
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	typedef itk::MedialCurveImageFilter< SkeletonAPITypes::InputImageType > MedialCurveFilter;
	MedialCurveFilter::Pointer medialFilter = MedialCurveFilter::New();
	medialFilter->SetInput( this->inputData );
	medialFilter->SetAverageOutwardFluxImage( aofFilter->GetOutput() );
	medialFilter->SetThreshold( this->threshold );
	medialFilter->Update();
	this->outputData = medialFilter->GetOutput();
}
Пример #2
0
int main(int argc, char *argv[])
{
	std::string inputFilenamesFilename = argv[1];
	double keyPointIntensityThreshold = atof(argv[2]);
	double dogSplitsPerOctave = atof(argv[3]);
	double statingScale = atof(argv[4]);
	double eLocation = atof(argv[5]);
	double eScale = std::log(atof(argv[6]));
	double eOrientation = atof(argv[7]);
	double gammaValue = atof(argv[8]);

	std::string distanceMapFilenamesFilename = argv[9];
	double extractionDistanceThreshold = atof(argv[10]);




	// load up the set of aligned images
	FilenamesReader::FilenamesType inputFilenames = FilenamesReader::Read(inputFilenamesFilename);
	FilenamesReader::FilenamesType distanceMapFilenames   = FilenamesReader::Read(distanceMapFilenamesFilename);
	ImageVolumeList images;
	RealVolumeList distanceMaps;
	for(unsigned int i = 0; i < inputFilenames.size(); i++)
	{
		ImageVolume::Pointer image = ImageVolumeIO::Read(inputFilenames[i]);
		images.push_back(image);
		RealVolume::Pointer distMap = RealVolumeIO::Read(distanceMapFilenames[i]);
		distanceMaps.push_back(distMap);
	}


	unsigned int sliceToTest = 7;

	// for each slice we want to learn the features
	const unsigned int sliceNum = images.front()->GetLargestPossibleRegion().GetSize()[2];
	for(unsigned int slice = sliceToTest; slice < sliceNum; slice++)
	{

		// get the set of slices that have some image data in them
		ImageSliceList validImages;
		RealSliceList validDistanceMaps;
		
		for(unsigned int im = 0; im < images.size(); im++)
		{
			ImageSlice::Pointer extractedSlice = ImageSlice::New();
			RealSlice::Pointer distanceSlice = RealSlice::New();
			ExtractSlice<ImageVolume, ImageSlice>(images[im], slice, extractedSlice);
			ExtractSlice<RealVolume, RealSlice>(distanceMaps[im], slice, distanceSlice);

			if(ImageContainsData(extractedSlice))
			{
				validDistanceMaps.push_back(distanceSlice);
				validImages.push_back(extractedSlice);
			}
		}

		/*
		if(validImages.size() < 3)
			continue;
		*/

		std::cout << "Slice Num: " << slice << " Image Number: " << validImages.size() << std::endl;



		typedef itk::Vector<double, 2> VectorType;
		typedef itk::Image<VectorType, 2> GradientType;
		typedef filter::HistogramOfGradeintsFeatureExtractor<GradientType> FeatureBuilderType;
		typedef FeatureBuilderType::FeatureType HoGFeatureType;
		std::vector<HoGFeatureType> allFeatures;
		std::vector<HoGFeatureType> allFeatures1;
		std::vector<HoGFeatureType> allFeatures2;

		

		unsigned int featureCount = 0;
		for(unsigned int im = 0; im < validImages.size(); im++)
		{
			ImageSlice::Pointer extractedSlice = validImages[im];

			// first we extract all of the keypoints points
			typedef filter::DoGKeyPointExtractor<utils::ImageSlice> ExtractorType;
			ExtractorType::Pointer extractor = ExtractorType::New();
			extractor->SetInput(extractedSlice);
			extractor->SetKeypointThreshold(keyPointIntensityThreshold);
			extractor->SetSplitsPerOctave(dogSplitsPerOctave);
			extractor->SetStartingSigma(statingScale);
			extractor->SetDistanceMap(validDistanceMaps[im]);
			extractor->SetDistanceThreshold(extractionDistanceThreshold);
			extractor->Update();

			// orientate the feature points
			typedef filter::KeyPointOrientator<utils::ImageSlice> Orientator;
			Orientator::Pointer orientator  = Orientator::New();
			orientator->SetInput(extractedSlice);
			orientator->SetKeyPoints(extractor->GetOutput());
			orientator->SetHistogramBins(32);
			orientator->SetSigmaScale(2);
			orientator->SetSampleRadius(5);
			orientator->Update();

			Orientator::OrientatedKeyPointMap orientateKeyPoints = orientator->GetOutput();


			

			// now we go through the features and compute the HOG descriptors
			Orientator::OrientatedKeyPointMap::iterator keyPointIt = orientateKeyPoints.begin();
			std::cout << orientateKeyPoints.size() << std::endl;
			while(keyPointIt != orientateKeyPoints.end())
			{
				double sigma = keyPointIt->first;
				Orientator::OrientatedKeyPointList keyPoints = keyPointIt->second;

				// smooth the image to the sigma level
				typedef itk::DiscreteGaussianImageFilter<utils::ImageSlice, utils::RealSlice> Smoother;
				Smoother::Pointer smoother = Smoother::New();
				smoother->SetInput(extractedSlice);
				smoother->SetVariance(sigma*sigma);
				smoother->SetUseImageSpacingOn();

				typedef itk::GradientRecursiveGaussianImageFilter<RealSlice, GradientType> GradientFilterType;
				GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
				gradientFilter->SetInput(smoother->GetOutput());
				//gradientFilter->SetSigma(sigma);
				gradientFilter->Update();



		
				


				std::cout << "Doing Sigma " << sigma << " Key Point Number: " << keyPoints.size() << std::endl;



				for(unsigned int fnum = 0; fnum < keyPoints.size(); fnum++)
				{
					Orientator::OrientatedKeyPoint keyPoint = keyPoints[fnum];

					// build the tranform
					typedef itk::CenteredRigid2DTransform<double> TransformType;
					TransformType::Pointer transform = TransformType::New();
					transform->SetCenter(keyPoint.location);
					transform->SetAngleInDegrees(360-keyPoint.degrees);

					// extract the patch from the gradient image
					typedef filter::ImagePatchExtractor<GradientType> PatchExtractorType;
					PatchExtractorType::Pointer patchExtractor = PatchExtractorType::New();
					patchExtractor->SetInput(gradientFilter->GetOutput());
					patchExtractor->SetTransform(transform);
					patchExtractor->SetScale(keyPoint.scale*2);

					PatchExtractorType::SizeType patchSize;
					patchSize.Fill(10);
					patchExtractor->SetPatchSize(patchSize);
					patchExtractor->SetInputPoint(keyPoint.location);
					patchExtractor->Update();


					/*
					// validate the keypoint
					typedef filter::StructureTensorKeyPointValidator<utils::ImageSlice> ValidatorType;
					ValidatorType::Pointer validator = ValidatorType::New();
					validator->SetInput(extractedSlice);	
					validator->SetKeyPoint(keyPoint);
					validator->SetRatio(validatorBeta);
					validator->Update();


					bool valid = validator->IsValid();
					*/


					// create the descriptor
					FeatureBuilderType::Pointer builder = FeatureBuilderType::New();
					builder->SetInput(patchExtractor->GetOutput());
					builder->SetOrientationBins(8);
					builder->SetKeyPoint(keyPoint);
					builder->Update();


					// add the feature to the list
					FeatureBuilderType::FeatureType feature = builder->GetOutput();
					feature.featureId = featureCount;
					allFeatures.push_back(feature);

					featureCount++;

				}



				
				keyPointIt++;
			}
		}

		




		std::cout << "Computing Distance Matrix" << std::endl;
		// compute the distance matrix
		typedef utils::DoubleMatrixType MatrixType;
		MatrixType distanceMatrix = MatrixType::Zero(allFeatures.size(), allFeatures.size());
		ComputeDifferenceMatrix(allFeatures, distanceMatrix);


		std::cout << "Grouping Features" << std::endl;
		// now we group the features by thier geometry
		typedef filter::FeaturePointGrouper<2> GrouperType;
		GrouperType::Pointer grouper = GrouperType::New();
		grouper->SetInput(allFeatures);
		grouper->SetAngleThreshold(eOrientation);
		grouper->SetLocationThreshold(eLocation);
		grouper->SetScaleThreshold(eScale);
		grouper->Update();





		std::cout << "Creating Clusters" << std::endl;
		GrouperType::FeatureGroupList clusters = grouper->GetOutput();
		std::sort(clusters.begin(), clusters.end());

		GrouperType::FeatureGroupList newClusters;

		for(unsigned int i = 0; i < clusters.size(); i++)
		{
			typedef filter::FeatureClusterLearner<2> ClusterLearnerType;
			ClusterLearnerType::Pointer learner = ClusterLearnerType::New();
			learner->SetInput(clusters[i]);
			learner->SetFeatures(allFeatures);
			learner->SetDistanceMatrix(distanceMatrix);
			learner->SetGamma(gammaValue);
			learner->Update();
			
			ClusterLearnerType::ClusterType newCluster = learner->GetOutput();
			newClusters.push_back(newCluster);



		}

		std::cout << "Culling Clusters" << std::endl;
		
		typedef filter::FeatureClusterCuller<2> Culler;
		Culler::Pointer culler = Culler::New();
		culler->SetInput(newClusters);
		culler->Update();


		Culler::ClusterList culledClusters = culler->GetOutput();
		std::sort(culledClusters.begin(), culledClusters.end());
		for(unsigned int i = 0; i < culledClusters.size(); i++)
		{
			typedef filter::ClusterDistributionGenerator<2> DistributionGenerator;
			DistributionGenerator::Pointer generator = DistributionGenerator::New();
			generator->SetInput(culledClusters[i]);
			generator->Update();

			exit(1);
		}



		/*


		ImageSlice::Pointer extractedSlice = ImageSlice::New();
		ExtractSlice<ImageVolume, ImageSlice>(images[0], sliceToTest, extractedSlice);

		std::vector<std::pair<int, ImageSlice::PointType> > testOut;
		for(unsigned int i = 0; i < culledClusters.size(); i++)
		{
			for(unsigned int j = 0; j < culledClusters[i].clusterMembers.size(); j++)
			{
			
				std::pair<int, ImageSlice::PointType> p(i, culledClusters[i].clusterMembers[j].keyPoint.location);
				testOut.push_back(p);				
			}			
		}




		utils::DoubleMatrixType pOut = utils::DoubleMatrixType::Zero(testOut.size(), 2);
		utils::IntMatrixType iOut = utils::IntMatrixType::Zero(testOut.size(),1);
		for(unsigned int i = 0; i < testOut.size(); i++)
		{
			itk::ContinuousIndex<double, 2> contIndex;
			extractedSlice->TransformPhysicalPointToContinuousIndex(testOut[i].second, contIndex);

			pOut(i,0) = contIndex[0];			
			pOut(i,1) = contIndex[1];

			iOut(i,0) = testOut[i].first;			
		}


	


		utils::MatrixDataSet::Pointer dout = utils::MatrixDataSet::New();
		dout->AddData("locations", pOut);
		dout->AddData("index", iOut);
		utils::MatrixWriter::Pointer writer = utils::MatrixWriter::New();
		writer->SetInput(dout);
		writer->SetFilename("data.hdf5");
		writer->Update();



		exit(1);
		*/

		


		/*
		// compute the affinity matrix between all of the features
		unsigned int numFeatures = allFeatures.size();
		double sum = 0.0;
		int count = 0;
		int max = 0;
		int maxId = 0;
		std::vector<int> counts;

		std::vector<Cluster> allGroups;

		// groupd all the features that have a similar location / scale / orientation
		for(unsigned int i = 0; i < numFeatures; i++)
		{
			Cluster cluster;
			cluster.featureIndex = i;
			cluster.feature = allFeatures[i];
			cluster.e = 0.0;
			cluster.members.push_back(allFeatures[i]);
			
			for(unsigned int j = 0; j < numFeatures; j++)
			{
				if(i == j) continue;
				if(AreSimilar(allFeatures[i], allFeatures[j],
							eLocation, eOrientation, eScale))
				{
					cluster.members.push_back(allFeatures[j]);
				}
			}
			
			counts.push_back(cluster.members.size());
			if(cluster.members.size() > max)
			{
				max = cluster.members.size();
				maxId = i;
			}

			allGroups.push_back(cluster);
			sum += cluster.members.size();
			std::sort(cluster.members.begin(), cluster.members.end(), member_sort);
			count++;
		}



		std::sort(counts.begin(), counts.end());
		for(unsigned int i = 0; i < counts.size(); i++)
		{
			std::cout << counts[i] << std::endl;
		}


		// compute the difference matrix
		utils::DoubleMatrixType diffMat;
		ComputeDifferenceMatrix(allFeatures, diffMat);

		// loop through the groups to form the clusters
		std::vector<Cluster> allClusters;
		for(unsigned int i = 0; i < allGroups.size(); i++)
		{
			Cluster cluster;
			CreateCluster(allGroups[i], allFeatures, diffMat, cluster);
			allClusters.push_back(cluster);
		}

		// remove duplicates
		std::vector<int> toRemove;
		for(unsigned int i = 0; i < allClusters.size(); i++)
		{
			bool duplicate = false;
			for(unsigned int j = i; j < allClusters.size(); j++)
			{
				if(i == j) continue;
				if(allClusters[i].members.size() != allClusters[j].members.size())
					continue;

				bool sameMembers = true;
				for(unsigned int k = 0; k < allClusters[i].members.size(); k++)
				{
					if(allClusters[i].members[k].index != allClusters[j].members[k].index)
					{
						sameMembers = false;				
						break;
					}
				}

				if(sameMembers)
				{
					duplicate = true;
				}

				if(duplicate) break;
			}
			if(duplicate) toRemove.push_back(i);

		}

		
		std::cout << allClusters.size() << std::endl;
		for(unsigned int i = 0; i < toRemove.size(); i++)
		{
	//		allClusters.erase(allGroups.begin()+(toRemove[i]-i));
		}
		std::cout << allClusters.size() << std::endl;

		// trim the clusters
		std::vector<Cluster> trimmedClusters;
		TrimClusters(allClusters, trimmedClusters);
		std::cout << trimmedClusters.size() << std::endl;

		std::vector<std::pair<int, ImageSlice::PointType> > testOut;


		for(unsigned int i = 0; i < trimmedClusters.size(); i++)
		{
			for(unsigned int j = 0; j < trimmedClusters[i].members.size(); j++)
			{
				std::pair<int, ImageSlice::PointType> p(i, trimmedClusters[i].members[j].location);
				testOut.push_back(p);				
			}			
			std::cout << trimmedClusters[i].members.size() << std::endl;
		}

		ImageSlice::Pointer extractedSlice = ImageSlice::New();
		ExtractSlice<ImageVolume, ImageSlice>(images[0], sliceToTest, extractedSlice);


		utils::DoubleMatrixType pOut = utils::DoubleMatrixType::Zero(testOut.size(), 2);
		utils::IntMatrixType iOut = utils::IntMatrixType::Zero(testOut.size(),1);
		for(unsigned int i = 0; i < testOut.size(); i++)
		{
			itk::ContinuousIndex<double, 2> contIndex;
			extractedSlice->TransformPhysicalPointToContinuousIndex(testOut[i].second, contIndex);

			pOut(i,0) = contIndex[0];			
			pOut(i,1) = contIndex[1];
			
			// compute the image indexes


			
	
			iOut(i,0) = testOut[i].first;			
		}


	


		utils::MatrixDataSet::Pointer dout = utils::MatrixDataSet::New();
		dout->AddData("locations", pOut);
		dout->AddData("index", iOut);
		utils::MatrixWriter::Pointer writer = utils::MatrixWriter::New();
		writer->SetInput(dout);
		writer->SetFilename("data.hdf5");
		writer->Update();
		exit(1);
		*/
	}

	return 0;
}
void QmitkBasicImageProcessing::StartButtonClicked()
{
  if(!m_SelectedImageNode->GetNode()) return;

  this->BusyCursorOn();

  mitk::Image::Pointer newImage;

  try
  {
    newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
  }
  catch ( std::exception &e )
  {
  QString exceptionString = "An error occured during image loading:\n";
  exceptionString.append( e.what() );
    QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
    this->BusyCursorOff();
    return;
  }

  // check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
  if ( (! newImage) || (newImage->IsInitialized() == false) )
  {
    this->BusyCursorOff();

    QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
    return;
  }

  // check if operation is done on 4D a image time step
  if(newImage->GetDimension() > 3)
  {
    mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
    timeSelector->SetInput(newImage);
    timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
    timeSelector->Update();
    newImage = timeSelector->GetOutput();
  }



  // check if image or vector image
  ImageType::Pointer itkImage = ImageType::New();
  VectorImageType::Pointer itkVecImage = VectorImageType::New();

  int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();

  if(isVectorImage > 1)
  {
    CastToItkImage( newImage, itkVecImage );
  }
  else
  {
    CastToItkImage( newImage, itkImage );
  }

  std::stringstream nameAddition("");

  int param1 = m_Controls->sbParam1->value();
  int param2 = m_Controls->sbParam2->value();
  double dparam1 = m_Controls->dsbParam1->value();
  double dparam2 = m_Controls->dsbParam2->value();
  double dparam3 = m_Controls->dsbParam3->value();

  try{

  switch (m_SelectedAction)
  {

  case GAUSSIAN:
    {
      GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
      gaussianFilter->SetInput( itkImage );
      gaussianFilter->SetVariance( param1 );
      gaussianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
      nameAddition << "_Gaussian_var_" << param1;
      std::cout << "Gaussian filtering successful." << std::endl;
      break;
    }

  case MEDIAN:
    {
      MedianFilterType::Pointer medianFilter = MedianFilterType::New();
      MedianFilterType::InputSizeType size;
      size.Fill(param1);
      medianFilter->SetRadius( size );
      medianFilter->SetInput(itkImage);
      medianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
      nameAddition << "_Median_radius_" << param1;
      std::cout << "Median Filtering successful." << std::endl;
      break;
    }

  case TOTALVARIATION:
    {
      if(isVectorImage > 1)
      {
        VectorTotalVariationFilterType::Pointer TVFilter
          = VectorTotalVariationFilterType::New();
        TVFilter->SetInput( itkVecImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }
      else
      {
        ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
        floatCaster->SetInput( itkImage );
        floatCaster->Update();
        FloatImageType::Pointer fImage = floatCaster->GetOutput();

        TotalVariationFilterType::Pointer TVFilter
          = TotalVariationFilterType::New();
        TVFilter->SetInput( fImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }

      nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
      std::cout << "Total Variation Filtering successful." << std::endl;
      break;
    }

  case DILATION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
      dilationFilter->SetInput( itkImage );
      dilationFilter->SetKernel( binaryBall );
      dilationFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
      nameAddition << "_Dilated_by_" << param1;
      std::cout << "Dilation successful." << std::endl;
      break;
    }

  case EROSION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
      erosionFilter->SetInput( itkImage );
      erosionFilter->SetKernel( binaryBall );
      erosionFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
      nameAddition << "_Eroded_by_" << param1;
      std::cout << "Erosion successful." << std::endl;
      break;
    }

  case OPENING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
      openFilter->SetInput( itkImage );
      openFilter->SetKernel( binaryBall );
      openFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
      nameAddition << "_Opened_by_" << param1;
      std::cout << "Opening successful." << std::endl;
      break;
    }

  case CLOSING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
      closeFilter->SetInput( itkImage );
      closeFilter->SetKernel( binaryBall );
      closeFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
      nameAddition << "_Closed_by_" << param1;
      std::cout << "Closing successful." << std::endl;
      break;
    }

  case GRADIENT:
    {
      GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
      gradientFilter->SetInput( itkImage );
      gradientFilter->SetSigma( param1 );
      gradientFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
      nameAddition << "_Gradient_sigma_" << param1;
      std::cout << "Gradient calculation successful." << std::endl;
      break;
    }

  case LAPLACIAN:
    {
      // the laplace filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
      laplacianFilter->SetInput( fImage );
      laplacianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
      nameAddition << "_Second_Derivative";
      std::cout << "Laplacian filtering successful." << std::endl;
      break;
    }

  case SOBEL:
    {
      // the sobel filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
      sobelFilter->SetInput( fImage );
      sobelFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
      nameAddition << "_Sobel";
      std::cout << "Edge Detection successful." << std::endl;
      break;
    }

  case THRESHOLD:
    {
      ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
      thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
      thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
      thFilter->SetInsideValue(1);
      thFilter->SetOutsideValue(0);
      thFilter->SetInput(itkImage);
      thFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
      nameAddition << "_Threshold";
      std::cout << "Thresholding successful." << std::endl;
      break;
    }

  case INVERSION:
    {
      InversionFilterType::Pointer invFilter = InversionFilterType::New();
      mitk::ScalarType min = newImage->GetScalarValueMin();
      mitk::ScalarType max = newImage->GetScalarValueMax();
      invFilter->SetMaximum( max + min );
      invFilter->SetInput(itkImage);
      invFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
      nameAddition << "_Inverted";
      std::cout << "Image inversion successful." << std::endl;
      break;
    }

  case DOWNSAMPLING:
    {
      ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
      downsampler->SetInput( itkImage );

      NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
      downsampler->SetInterpolator( interpolator );

      downsampler->SetDefaultPixelValue( 0 );

      ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
      spacing *= (double) param1;
      downsampler->SetOutputSpacing( spacing );

      downsampler->SetOutputOrigin( itkImage->GetOrigin() );
      downsampler->SetOutputDirection( itkImage->GetDirection() );

      ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
      for ( int i = 0; i < 3; ++i )
      {
        size[i] /= param1;
      }
      downsampler->SetSize( size );
      downsampler->UpdateLargestPossibleRegion();

      newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
      nameAddition << "_Downsampled_by_" << param1;
      std::cout << "Downsampling successful." << std::endl;
      break;
    }

  case FLIPPING:
    {
      FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
      flipper->SetInput( itkImage );
      itk::FixedArray<bool, 3> flipAxes;
      for(int i=0; i<3; ++i)
      {
        if(i == param1)
        {
          flipAxes[i] = true;
        }
        else
        {
          flipAxes[i] = false;
        }
      }
      flipper->SetFlipAxes(flipAxes);
      flipper->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
      std::cout << "Image flipping successful." << std::endl;
      break;
    }

  case RESAMPLING:
    {
      std::string selectedInterpolator;
      ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
      switch (m_SelectedInterpolation)
      {
      case LINEAR:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      case NEAREST:
        {
          NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Nearest";
          break;
        }
      default:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      }
      resampler->SetInput( itkImage );
      resampler->SetOutputOrigin( itkImage->GetOrigin() );

      ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
      ImageType::SpacingType input_spacing = itkImage->GetSpacing();

      ImageType::SizeType output_size;
      ImageType::SpacingType output_spacing;

      output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
      output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
      output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
      output_spacing [0] = dparam1;
      output_spacing [1] = dparam2;
      output_spacing [2] = dparam3;

      resampler->SetSize( output_size );
      resampler->SetOutputSpacing( output_spacing );
      resampler->SetOutputDirection( itkImage->GetDirection() );

      resampler->UpdateLargestPossibleRegion();

      ImageType::Pointer resampledImage = resampler->GetOutput();

      newImage = mitk::ImportItkImage( resampledImage );
      nameAddition << "_Resampled_" << selectedInterpolator;
      std::cout << "Resampling successful." << std::endl;
      break;
    }


  case RESCALE:
    {
      FloatImageType::Pointer floatImage = FloatImageType::New();
      CastToItkImage( newImage, floatImage );
      itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
      filter->SetInput(0, floatImage);
      filter->SetOutputMinimum(dparam1);
      filter->SetOutputMaximum(dparam2);
      filter->Update();
      floatImage = filter->GetOutput();

      newImage = mitk::Image::New();
      newImage->InitializeByItk(floatImage.GetPointer());
      newImage->SetVolume(floatImage->GetBufferPointer());
      nameAddition << "_Rescaled";
      std::cout << "Rescaling successful." << std::endl;

      break;
    }

  default:
    this->BusyCursorOff();
    return;
  }
  }
  catch (...)
  {
    this->BusyCursorOff();
    QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
    return;
  }

  newImage->DisconnectPipeline();

  // adjust level/window to new image
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( newImage );
  mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
  levWinProp->SetLevelWindow( levelwindow );

  // compose new image name
  std::string name = m_SelectedImageNode->GetNode()->GetName();
  if (name.find(".pic.gz") == name.size() -7 )
  {
    name = name.substr(0,name.size() -7);
  }
  name.append( nameAddition.str() );

  // create final result MITK data storage node
  mitk::DataNode::Pointer result = mitk::DataNode::New();
  result->SetProperty( "levelwindow", levWinProp );
  result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
  result->SetData( newImage );

  // for vector images, a different mapper is needed
  if(isVectorImage > 1)
  {
    mitk::VectorImageMapper2D::Pointer mapper =
      mitk::VectorImageMapper2D::New();
    result->SetMapper(1,mapper);
  }

  // reset GUI to ease further processing
//  this->ResetOneImageOpPanel();

  // add new image to data storage and set as active to ease further processing
  GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
  if ( m_Controls->cbHideOrig->isChecked() == true )
    m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
  // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);

  // show the results
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  this->BusyCursorOff();
}
Пример #4
0
    void IntensityForce::ComputeIntensityForce(ParticleSystem* system) {
        ParticleSubjectArray& shapes = system->GetSubjects();
        const ParticleSubject& meanSubject = system->GetMeanSubject();
        
        const int nSubj = shapes.size();
        const int nPoints = shapes[0].GetNumberOfPoints();
        const int nRadius = 2;
        const int nAttrsPerPoint = ::pow(2*nRadius+1, __Dim);
        const int nAttrs = nPoints * nAttrsPerPoint;

        DoubleImageVector warpedImages(nSubj);
        VectorImageVector gradImages(nSubj);

        double* attrs = new double[nSubj * nAttrs];
        double* gradAttrs = new double[nSubj * nAttrs * __Dim];
        double* force = new double[nSubj * nPoints * __Dim];

        // first create a warped image into the mean transform space
        // second create a gradient vector image per subject
        // third extract attributes (features)
        for (int i = 0; i < nSubj; i++) {
            ParticleSubject& subject = shapes[i];
            ParticleBSpline bspline;
            bspline.SetReferenceImage(m_ImageContext->GetLabel(i));
            bspline.EstimateTransform(meanSubject, subject);
            FieldTransformType::Pointer fieldTransform = bspline.GetTransform();
            CompositeTransformType::Pointer transform = CompositeTransformType::New();
            transform->AddTransform(fieldTransform);
            subject.m_InverseTransform = transform;
            warpedImages[i] = bspline.WarpImage(m_ImageContext->GetDoubleImage(i));
            GradientFilterType::Pointer grad = GradientFilterType::New();
            grad->SetInput(warpedImages[i]);
            grad->Update();
            gradImages[i] = grad->GetOutput();

            // extract attributes
            DoubleImage::SizeType radius;
            radius.Fill(nRadius);
            DoubleImageNeighborhoodIteratorType iiter(radius, warpedImages[i], warpedImages[i]->GetBufferedRegion());
            VectorImageNeighborhoodIteratorType giter(radius, gradImages[i], gradImages[i]->GetBufferedRegion());

            DoubleImage::IndexType idx;
            #pragma omp parallel for
            for (int j = 0; j < nPoints; j++) {
                Particle& par = subject.m_Particles[j];
                fordim(k) {
                    idx[k] = round(par.y[k]);
                }
                iiter.SetLocation(idx);
                giter.SetLocation(idx);

                double* jAttrs = &attrs[i * nAttrs + j * nAttrsPerPoint];
                double* jAttrsGrad = &gradAttrs[(i * nAttrs + j * nAttrsPerPoint) * __Dim];
                const int numAttrs = iiter.Size();
                assert(numAttrs == nAttrsPerPoint);
                for (int k = 0; k < nAttrsPerPoint; k++) {
                    double pixel = iiter.GetPixel(k);
                    VectorType grad = giter.GetPixel(k);
                    jAttrs[k] = pixel;
                    for (int m = 0; m < __Dim; m++) {
                        jAttrsGrad[m] = grad[m];
                    }
                }
            }
        }


        // column sum
        double* sumAttrs = new double[nPoints * nAttrsPerPoint];
        #pragma omp parallel for
        for (int j = 0; j < nAttrs; j++) {
            sumAttrs[j] = 0;
            for (int i = 0; i < nSubj; i++) {
                sumAttrs[j] += attrs[i * nAttrs + j];
            }
        }

        // compute mean differences
        for (int i = 0; i < nSubj; i++) {
            #pragma omp parallel for
            for (int j = 0; j < nAttrs; j++) {
                attrs[i * nAttrs + j] -= (sumAttrs[j] / nSubj);
            }
        }

        // compute force direction
        memset(force, 0, nSubj * nPoints * __Dim * sizeof(double));
        for (int i = 0; i < nSubj; i++) {
            #pragma omp parallel for
            for (int j = 0; j < nPoints; j++) {
                double* forcePtr = &force[(i * nPoints + j) * __Dim];
                for (int k = 0; k < nAttrsPerPoint; k++) {
                    double attr = attrs[i * nAttrs + j * nAttrsPerPoint];
                    double* gradAttrPtr = &gradAttrs[(i * nAttrs + j * nAttrsPerPoint + k) * __Dim];
                    for (int m = 0; m < __Dim; m++) {
                        forcePtr[m] += attr * gradAttrPtr[m];
                    }
                }
            }
        }


        // compute force at subject space
        for (int i = 0; i < nSubj; i++) {
            CompositeTransformType::Pointer transform = shapes[i].m_InverseTransform;
            for (int j = 0; j < nPoints; j++) {
                double* forcePtr = &force[(i * nPoints + j) * __Dim];
                CompositeTransformType::InputPointType x;
                fordim(k) {
                    x[k] = shapes[i][j].x[k];
                }
                CompositeTransformType::JacobianType jac;
                jac.set_size(__Dim, __Dim);
                transform->ComputeInverseJacobianWithRespectToPosition(x, jac);
                fordim(k) {
                    double ff = 0;
                    if (__Dim == 3) {
                        ff = jac[0][k]*forcePtr[k] + jac[1][k]*forcePtr[k] + jac[2][k]*forcePtr[k];
                    } else if (__Dim == 2) {
                        ff = jac[0][k]*forcePtr[k] + jac[1][k]*forcePtr[k];
                    }
                    forcePtr[k] = ff;
                }
            }
        }

        for (int i = 0; i < nSubj; i++) {
            ParticleSubject& subj = shapes[i];
            for (int j = 0; j < nPoints; j++) {
                Particle& par = subj[j];
                VNLVector ff(__Dim);
                fordim (k) {
                    const int forceIdx = (i * nPoints + j) * __Dim;
                    ff[k] = force[forceIdx + k];
                }
                ff.normalize();
                par.SubForce(ff.data_block(), m_Coeff);
            }
        }


        delete[] force;
        delete[] attrs;
        delete[] gradAttrs;
    }
void CriminisiInpainting::ComputeBoundaryNormals()
{
  try
  {
    // Blur the mask, compute the gradient, then keep the normals only at the original mask boundary
    
    if(this->DebugImages)
      {
      Helpers::WriteImage<UnsignedCharScalarImageType>(this->BoundaryImage, "Debug/ComputeBoundaryNormals.BoundaryImage.mha");
      Helpers::WriteImage<Mask>(this->CurrentMask, "Debug/ComputeBoundaryNormals.CurrentMask.mha");
      }
      
    // Blur the mask
    typedef itk::DiscreteGaussianImageFilter< Mask, FloatScalarImageType >  BlurFilterType;
    BlurFilterType::Pointer gaussianFilter = BlurFilterType::New();
    gaussianFilter->SetInput(this->CurrentMask);
    gaussianFilter->SetVariance(2);
    gaussianFilter->Update();

    if(this->DebugImages)
      {
      Helpers::WriteImage<FloatScalarImageType>(gaussianFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BlurredMask.mha");
      }

    // Compute the gradient of the blurred mask
    typedef itk::GradientImageFilter< FloatScalarImageType, float, float>  GradientFilterType;
    GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
    gradientFilter->SetInput(gaussianFilter->GetOutput());
    gradientFilter->Update();

    if(this->DebugImages)
      {
      Helpers::WriteImage<FloatVector2ImageType>(gradientFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BlurredMaskGradient.mha");
      }

    // Only keep the normals at the boundary
    typedef itk::MaskImageFilter< FloatVector2ImageType, UnsignedCharScalarImageType, FloatVector2ImageType > MaskFilterType;
    MaskFilterType::Pointer maskFilter = MaskFilterType::New();
    //maskFilter->SetInput1(gradientFilter->GetOutput());
    //maskFilter->SetInput2(this->BoundaryImage);
    maskFilter->SetInput(gradientFilter->GetOutput());
    maskFilter->SetMaskImage(this->BoundaryImage);
    maskFilter->Update();

    if(this->DebugImages)
      {
      Helpers::WriteImage<FloatVector2ImageType>(maskFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BoundaryNormalsUnnormalized.mha");
      }
      
    //this->BoundaryNormals = maskFilter->GetOutput();
    //this->BoundaryNormals->Graft(maskFilter->GetOutput());
    Helpers::DeepCopy<FloatVector2ImageType>(maskFilter->GetOutput(), this->BoundaryNormals);

    // Normalize the vectors because we just care about their direction (the Data term computation calls for the normalized boundary normal)
    itk::ImageRegionIterator<FloatVector2ImageType> boundaryNormalsIterator(this->BoundaryNormals, this->BoundaryNormals->GetLargestPossibleRegion());
    itk::ImageRegionConstIterator<UnsignedCharScalarImageType> boundaryIterator(this->BoundaryImage, this->BoundaryImage->GetLargestPossibleRegion());

    while(!boundaryNormalsIterator.IsAtEnd())
      {
      if(boundaryIterator.Get()) // The pixel is on the boundary
        {
        FloatVector2ImageType::PixelType p = boundaryNormalsIterator.Get();
        p.Normalize();
        boundaryNormalsIterator.Set(p);
        }
      ++boundaryNormalsIterator;
      ++boundaryIterator;
      }

    if(this->DebugImages)
      {
      Helpers::WriteImage<FloatVector2ImageType>(this->BoundaryNormals, "Debug/ComputeBoundaryNormals.BoundaryNormals.mha");
      }
  }
  catch( itk::ExceptionObject & err )
  {
    std::cerr << "ExceptionObject caught in ComputeBoundaryNormals!" << std::endl;
    std::cerr << err << std::endl;
    exit(-1);
  }
}
void CriminisiInpainting::ComputeIsophotes()
{
  
  try
  {
    Helpers::DebugWriteImageConditional<FloatVectorImageType>(this->CurrentImage, "Debug/ComputeIsophotes.input.mha", this->DebugImages);
    
    /*
    // This only works when the image is RGB
    typedef itk::VectorMagnitudeImageFilter<FloatVectorImageType, UnsignedCharScalarImageType>  VectorMagnitudeFilterType;
    VectorMagnitudeFilterType::Pointer magnitudeFilter = VectorMagnitudeFilterType::New();
    magnitudeFilter->SetInput(this->OriginalImage); // We use the original image here because the image that has been painted green inside the hole has a strong gradient around the hole.
    magnitudeFilter->Update();
    */
    RGBImageType::Pointer rgbImage = RGBImageType::New();
    Helpers::VectorImageToRGBImage(this->OriginalImage, rgbImage);
    
    Helpers::DebugWriteImageConditional<RGBImageType>(rgbImage, "Debug/ComputeIsophotes.rgb.mha", this->DebugImages);

    typedef itk::RGBToLuminanceImageFilter< RGBImageType, FloatScalarImageType > LuminanceFilterType;
    LuminanceFilterType::Pointer luminanceFilter = LuminanceFilterType::New();
    luminanceFilter->SetInput(rgbImage);
    luminanceFilter->Update();
  
    Helpers::DebugWriteImageConditional<FloatScalarImageType>(luminanceFilter->GetOutput(), "Debug/ComputeIsophotes.luminance.mha", this->DebugImages);
    
    // Blur the image to compute better gradient estimates
    typedef itk::DiscreteGaussianImageFilter<FloatScalarImageType, FloatScalarImageType >  BlurFilterType;
    BlurFilterType::Pointer blurFilter = BlurFilterType::New();
    blurFilter->SetInput(luminanceFilter->GetOutput());
    blurFilter->SetVariance(2);
    blurFilter->Update();

    Helpers::DebugWriteImageConditional<FloatScalarImageType>(blurFilter->GetOutput(), "Debug/ComputeIsophotes.blurred.mha", true);
    
    // Compute the gradient
    // Template parameters are <TInputImage, TOperatorValueType, TOutputValueType>
    typedef itk::GradientImageFilter<FloatScalarImageType, float, float>  GradientFilterType;
    GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
    gradientFilter->SetInput(blurFilter->GetOutput());
    gradientFilter->Update();

    Helpers::DebugWriteImageConditional<FloatVector2ImageType>(gradientFilter->GetOutput(), "Debug/ComputeIsophotes.gradient.mha", this->DebugImages);
 
    // Rotate the gradient 90 degrees to obtain isophotes from gradient
    typedef itk::UnaryFunctorImageFilter<FloatVector2ImageType, FloatVector2ImageType,
    RotateVectors<
      FloatVector2ImageType::PixelType,
      FloatVector2ImageType::PixelType> > FilterType;

    FilterType::Pointer rotateFilter = FilterType::New();
    rotateFilter->SetInput(gradientFilter->GetOutput());
    rotateFilter->Update();

    Helpers::DebugWriteImageConditional<FloatVector2ImageType>(rotateFilter->GetOutput(), "Debug/ComputeIsophotes.rotatedGradient.mha", this->DebugImages);
      
    // Mask the isophote image with the expanded version of the inpainting mask.
    // That is, keep only the values outside of the expanded mask. To do this, we have to first invert the mask.

    // Invert the mask
    typedef itk::InvertIntensityImageFilter <Mask> InvertIntensityImageFilterType;
    InvertIntensityImageFilterType::Pointer invertMaskFilter = InvertIntensityImageFilterType::New();
    invertMaskFilter->SetInput(this->CurrentMask);
    invertMaskFilter->Update();

    if(this->DebugImages)
      {
      Helpers::WriteImage<Mask>(invertMaskFilter->GetOutput(), "Debug/ComputeIsophotes.invertedMask.mha");
      }

    //std::cout << "rotateFilter: " << rotateFilter->GetOutput()->GetLargestPossibleRegion() << std::endl;
    //std::cout << "invertMaskFilter: " << invertMaskFilter->GetOutput()->GetLargestPossibleRegion() << std::endl;
    
    // Keep only values outside the masked region
    typedef itk::MaskImageFilter< FloatVector2ImageType, Mask, FloatVector2ImageType > MaskFilterType;
    MaskFilterType::Pointer maskFilter = MaskFilterType::New();
    maskFilter->SetInput1(rotateFilter->GetOutput());
    maskFilter->SetInput2(invertMaskFilter->GetOutput());
    maskFilter->Update();

    if(this->DebugImages)
      {
      Helpers::WriteImage<FloatVector2ImageType>(maskFilter->GetOutput(), "Debug/ComputeIsophotes.maskedIsophotes.mha");
      }
      
    Helpers::DeepCopy<FloatVector2ImageType>(maskFilter->GetOutput(), this->IsophoteImage);
   
  }
  catch( itk::ExceptionObject & err )
  {
    std::cerr << "ExceptionObject caught in ComputeIsophotes!" << std::endl;
    std::cerr << err << std::endl;
    exit(-1);
  }
}
void myVtkInteractorStyleImage3D::RemoveLeaks(){
	boost::mutex::scoped_lock scoped_lock(_canSegment_mutex);
	if (!_foundLeaks){
		cout << "Final segmentation had no leaks!" << endl;
		vtkSmartPointer<vtkNIFTIImageWriter> niw = vtkSmartPointer<vtkNIFTIImageWriter>::New();
		vtkStructuredPoints* saveMat = vtkStructuredPoints::New();
		cout << "At filtering." << endl;
		saveMat->DeepCopy(_selection);
		vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(saveMat->GetPointData()->GetScalars());
		for (int i = 0; i < saveMat->GetNumberOfPoints(); i++){
			if (scalars->GetValue(i) == BACKGROUND){
				scalars->SetValue(i, NOT_ACTIVE);
			}
		}
		scalars->Modified();
		//dilate:
		cout << "at dilation" << endl;
		vtkSmartPointer<vtkImageDilateErode3D> dilateErode =
			vtkSmartPointer<vtkImageDilateErode3D>::New();
		dilateErode->SetInputData(saveMat);
		dilateErode->SetDilateValue(FOREGROUND);
		dilateErode->SetErodeValue(NOT_ACTIVE);
		dilateErode->SetKernelSize(DILATION_ST_SIZE, DILATION_ST_SIZE, 1);
		dilateErode->ReleaseDataFlagOff();
		dilateErode->Update();
		cout << "finished dilation" << endl;

		cout << "Saving..." << endl;
		niw->SetInputData(dilateErode->GetOutput());
		niw->SetFileName("correctedImage.nii.gz");
		niw->Write();
		cout << "Final segmentation was saved successfully!" << endl;
		return;
	}
	cout << "Started fixing mesh!" << endl;
	typedef double PixelType;
	typedef unsigned short SegPixelType;
	const unsigned char dim = 3;

	typedef itk::Image<PixelType, dim> ImageType;
	typedef itk::Image<SegPixelType, dim> SegImageType;

	MeshLeaksCorrector mlc;
	ImageType::Pointer inputImage = mlc.read3DImage<ImageType>(_inputName.c_str());
	cout << "Image reading done." << endl;
	typedef itk::GradientMagnitudeImageFilter<ImageType, ImageType> GradientFilterType;
	GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
	gradientFilter->SetInput(inputImage);
	gradientFilter->Update();
	ImageType::Pointer gradientInputImage = gradientFilter->GetOutput();

	cout << "Produced gradient image" << endl;
	typedef itk::ImageRegionIterator<ImageType> IteratorType;
	typedef itk::ImageRegionIterator<SegImageType> SegIteratorType;

	IteratorType gradIt(gradientFilter->GetOutput(), gradientFilter->GetOutput()->GetLargestPossibleRegion());
	cout << "GradIt" << endl;
	vtkPolyDataMapper* mapper = (vtkPolyDataMapper*)(this->GetDefaultRenderer()->GetActors()->GetLastActor()->GetMapper());
	vtkSmartPointer<vtkPolyData> vtkSegImage = vtkSmartPointer<vtkPolyData>::New();
	vtkSegImage->DeepCopy(mapper->GetInput());
	vtkSegImage->GetPointData()->SetScalars(NULL);

	cout << "Extracted mesh from actor" << endl;

	vtkSmartPointer<vtkSmoothPolyDataFilter> smoother = vtkSmoothPolyDataFilter::New();
	smoother->SetInputData(vtkSegImage);
	smoother->SetNumberOfIterations(MESH_SMOOTH_ITERATIONS);
	smoother->Update();
	vtkSmartPointer<vtkPolyData> mesh = smoother->GetOutput();
	cout << "Mesh smoothed" << endl;
	typedef itk::ImageToVTKImageFilter<ImageType> ConverterType;
	ConverterType::Pointer gradientConverter = ConverterType::New();
	gradientConverter->SetInput(inputImage);
	gradientConverter->Update();
	vtkSmartPointer<vtkImageData> vtkGradientImage = gradientConverter->GetOutput();

	cout << "Read CT image" << endl;

	vtkSmartPointer<vtkProbeFilter> probeFilter = vtkProbeFilter::New();
	probeFilter->SetSourceData(vtkGradientImage);
	probeFilter->SetInputData(mesh);
	probeFilter->Update();

	cout << "Probe finished" << endl;
	vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkGeometryFilter::New();
	geometryFilter->SetInputData(probeFilter->GetOutput());
	geometryFilter->Update();
	vtkSmartPointer<vtkPolyData> gradientMesh = geometryFilter->GetOutput();

	cout << "Geometric filter finished" << endl;

	vtkSmartPointer<vtkPolyData> minCurvatureMesh = mlc.polyDataToMinCurvature(mapper->GetInput());
	cout << "mlc.minCurv finished" << endl;

	//just temporary - don't forget to delete
	vtkSmartPointer<vtkPolyData> maxCurvatureMesh = mlc.polyDataToMaxCurvature(mapper->GetInput());
	//  --- up to here
	cout << "mlc.maaxCurv finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMeshLeaks = mlc.minCut(minCurvatureMesh, mapper->GetInput(), gradientMesh, MIN_CURVATURE_TAG, 1.0f);
	cout << "minCut finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMeshInteriorLeaks = mlc.minCut(maxCurvatureMesh, mapper->GetInput(), gradientMesh, MAX_CURVATURE_TAG, 1.0f);
	cout << "minCut Interior finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMesh = mlc.minCutConjunction(minCutMeshLeaks, minCutMeshInteriorLeaks);
	cout << "Conjunction finished" << endl;
	mlc.attributeDilation(minCutMesh, ATTRIBUTE_DILATION_RADIUS);
	cout << "dilation finished" << endl;
	vtkSmartPointer<vtkPolyData> correctedMesh1 = mlc.laplaceInterpolation(minCutMesh);
	cout << "laplace finished" << endl;
	vtkSmartPointer<vtkPolyDataNormals> normals = vtkPolyDataNormals::New();
	normals->SetInputData(correctedMesh1);
	normals->FlipNormalsOn();
	normals->Update();
	vtkSmartPointer<vtkPolyData> correctedMesh = normals->GetOutput();
	cout << "Finished fixing mesh! Wow...." << endl;
	cout << "Writing mesh to file! laplaceMesh.vtk" << endl;
	mlc.writePolyData(correctedMesh, "laplaceMesh.vtk");
	vtkSmartPointer<vtkDecimatePro> decimateFilter = vtkDecimatePro::New();
	decimateFilter->SetInputData(correctedMesh);
	decimateFilter->SetTargetReduction(DECIMATION_FACTOR);
	decimateFilter->PreserveTopologyOn();
	decimateFilter->Update();
	vtkSmartPointer<vtkPolyData> decimatedMesh = decimateFilter->GetOutput();
	cout << "Writing mesh to file! decimatedMesh.vtk" << endl;
	mlc.writePolyData(decimatedMesh, "decimatedMesh.vtk");
	//2.5D NEW code
	//Seg input image is the selection_structured_points. (upcast to vtkImageData)
	typedef itk::VTKImageToImageFilter<SegImageType> SegConverterType;
	SegConverterType::Pointer converter = SegConverterType::New();
	cout << "bedug 1" << endl;
	// selection is not NULL (checked...)
	cout << "this->_selection->GetScalarType(): " << this->_selection->GetScalarType() << endl;
	if (this->_selection->GetScalarType() == VTK_INT){
		cout << "I have INTs instead of shorts for some reason!" << endl;
	}
	converter->SetInput(this->_selection);
	cout << "deb 5" << endl;
	converter->Update(); // 
	cout << "bedug 2" << endl;
	SegImageType::Pointer segInputImage = converter->GetOutput();
	cout << "bedug 3" << endl;
	SegImageType::Pointer outputContourImage = mlc.sampleMeshOnImage<SegImageType>(decimatedMesh, segInputImage);
	cout << "bedug 4" << endl;
	vtkSmartPointer<vtkDecimatePro> decimateFilter2 = vtkDecimatePro::New();
	decimateFilter2->SetInputData(mapper->GetInput());
	decimateFilter2->SetTargetReduction(DECIMATION_FACTOR);
	decimateFilter2->PreserveTopologyOn();
	decimateFilter2->Update();
	SegImageType::Pointer seedInputImage = mlc.sampleMeshOnImage<SegImageType>(decimateFilter2->GetOutput(), segInputImage);
	cout << "bedug 5" << endl;
	SegImageType::Pointer outputImage = mlc.correctImage<SegImageType>(segInputImage, seedInputImage, outputContourImage, _numTumors);

	//Here we should dilate:
	cout << "at dilation" << endl;
	typedef itk::BinaryBallStructuringElement<SegPixelType,3> StructuringElementType;
	StructuringElementType structuringElement;
	structuringElement.SetRadius(DILATION_ST_SIZE);
	structuringElement.CreateStructuringElement();

	typedef itk::BinaryDilateImageFilter<SegImageType, SegImageType, StructuringElementType>
		BinaryDilateImageFilterType;

	BinaryDilateImageFilterType::Pointer dilateFilter
		= BinaryDilateImageFilterType::New();
	dilateFilter->SetInput(outputImage);
	dilateFilter->SetKernel(structuringElement);
	dilateFilter->Update();
	outputImage = dilateFilter->GetOutput();
	cout << "finished dilation" << endl;

	//dilation end.

	typedef itk::ImageFileWriter<SegImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	cout << "bedug 6" << endl;
	writer->SetInput(outputImage);
	cout << "Writing mesh to file! correctedImage.nii.gz" << endl;
	writer->SetFileName("correctedImage.nii.gz");
	try{
		writer->Update();
	}
	catch (itk::ExceptionObject & excp)
	{
		std::cerr << "writing input image exception thrown" << std::endl;
		std::cerr << excp << std::endl;
		exit(1);
	}

	typedef itk::ImageToVTKImageFilter<SegImageType> SegInvConverterType;
	SegInvConverterType::Pointer correctionConverter = SegInvConverterType::New();
	cout << "bedug 7" << endl;
	correctionConverter->SetInput(outputImage);
	correctionConverter->Update();
	vtkSmartPointer<vtkImageData> vtkCorrectedImage = correctionConverter->GetOutput();
	vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(vtkCorrectedImage->GetPointData()->GetScalars());
	vtkUnsignedShortArray* selection_scalars = (vtkUnsignedShortArray*)(_selection->GetPointData()->GetScalars());
	for (int i = 0; i < _selection->GetNumberOfPoints(); i++){	
		if (scalars->GetValue(i) != NOT_ACTIVE){
			//cout << scalars->GetValue(i) << endl;
			selection_scalars->SetValue(i, FOREGROUND);
		}
		else{
			selection_scalars->SetValue(i, NOT_ACTIVE);
		}
	}
	selection_scalars->Modified();
	this->_selection->Modified();

	cout << "bedug 8" << endl;
	vtkSmartPointer<vtkPolyData> outputMesh = mlc.createAndSmoothSurface(vtkCorrectedImage, 50);

	vtkUnsignedShortArray* meshScalars = vtkUnsignedShortArray::New();// (vtkUnsignedShortArray*)(outputMesh->GetPointData()->GetScalars());
	meshScalars->SetNumberOfComponents(1);
	meshScalars->SetNumberOfTuples(outputMesh->GetNumberOfPoints());
	cout <<"outputMesh->GetNumberOfPoints()"<< outputMesh->GetNumberOfPoints() << endl;
	for (int i = 0; i < outputMesh->GetNumberOfPoints(); i++){
		meshScalars->SetValue(i, NOT_ACTIVE);
	}
	meshScalars->SetName("mesh_colors");
	meshScalars->Modified(); 
	outputMesh->GetPointData()->RemoveArray("mesh_colors");
	outputMesh->GetPointData()->SetScalars(meshScalars);
	outputMesh->GetPointData()->Modified();
	cout << "output values: " << meshScalars->GetValue(0) << endl;
	mapper->GetInput()->DeepCopy(outputMesh);
	mapper->Modified();
	cout << "We won!" << endl;
}
void BoundaryNormals::ComputeBoundaryNormals(TNormalsImage* const boundaryNormalsImage, const float maskBlurVariance)
{
  // Blur the mask, compute the gradient, then keep the normals only at the original mask boundary

  // Compute the boundary of the mask
  typedef itk::Image<unsigned char, 2> BoundaryImageType;
  BoundaryImageType::Pointer boundaryImage = BoundaryImageType::New();
  this->MaskImage->CreateBoundaryImage(boundaryImage, Mask::VALID, 255);

  if(this->IsDebugOn())
  {
    ITKHelpers::WriteImage(boundaryImage.GetPointer(),
                           "ComputeBoundaryNormals.BoundaryImage.mha");
  }

  // Blur the mask so that the normals are not quantized so much. Also, pixels with only diagonal
  // valid neighbors have undefined gradients without this blurring.
  typedef itk::DiscreteGaussianImageFilter<Mask, ITKHelpers::FloatScalarImageType>  BlurFilterType;
  BlurFilterType::Pointer gaussianFilter = BlurFilterType::New();
  gaussianFilter->SetInput(this->MaskImage);
  gaussianFilter->SetVariance(maskBlurVariance);
  gaussianFilter->Update();

  if(this->IsDebugOn())
  {
     ITKHelpers::WriteImage(gaussianFilter->GetOutput(),
                            "ComputeBoundaryNormals.BlurredMask.mha");
  }

  // Compute the gradient of the blurred mask
  typedef itk::GradientImageFilter<ITKHelpers::FloatScalarImageType, float, float>  GradientFilterType;
  GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
  gradientFilter->SetInput(gaussianFilter->GetOutput());
  gradientFilter->Update();

  if(this->IsDebugOn())
  {
    ITKHelpers::WriteImage(gradientFilter->GetOutput(),
                          "ComputeBoundaryNormals.BlurredMaskGradient.mha");
  }

  // Only keep the normals at the boundary
  typedef itk::MaskImageFilter<TNormalsImage, ITKHelpers::UnsignedCharScalarImageType, TNormalsImage> MaskFilterType;
  typename MaskFilterType::Pointer maskFilter = MaskFilterType::New();
  maskFilter->SetInput(gradientFilter->GetOutput());
  maskFilter->SetMaskImage(boundaryImage);
  maskFilter->Update();

  if(this->IsDebugOn())
  {
    ITKHelpers::WriteImage(maskFilter->GetOutput(),
                           "ComputeBoundaryNormals.BoundaryNormalsUnnormalized.mha");
  }

  // Allocate the image to return
//  ITKHelpers::DeepCopy(maskFilter->GetOutput(), boundaryNormalsImage);
  ITKHelpers::InitializeImage(boundaryNormalsImage, this->MaskImage->GetLargestPossibleRegion());

  // Normalize the vectors because we just care about their direction
  std::vector<itk::Index<2> > boundaryPixels = ITKHelpers::GetNonZeroPixels(boundaryImage.GetPointer());

  for(std::vector<itk::Index<2> >::const_iterator boundaryPixelIterator = boundaryPixels.begin();
      boundaryPixelIterator != boundaryPixels.end(); ++boundaryPixelIterator)
  {
    typename TNormalsImage::PixelType p = maskFilter->GetOutput()->GetPixel(*boundaryPixelIterator);
    p.Normalize();
    boundaryNormalsImage->SetPixel(*boundaryPixelIterator, p);
  }

}
int main(int argc, const char *argv[])
{
	// Validate input parameters
	if (argc < 15) {
		std::cerr << "Missing parameters! Usage:" << std::endl;
		std::cerr << argv[0];
		std::cerr << " <Read/WriteDir> <InputImg> <OutputImg> ";
		std::cerr << "[seedX] [seedY] [seedZ] [initDist] ";
		std::cerr << "[sigma] [sigmoid K1] [sigmoid K2] ";
		std::cerr << "[propagation] [curvature] [advection] [iterations]";
		std::cerr << std::endl;
		return EXIT_FAILURE;
	}
	
	const unsigned int Dimension = 3;
	typedef float InputPixelType;
	typedef unsigned char OutputPixelType;
    typedef itk::Image< InputPixelType, Dimension > InputImageType;
	typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

    ////////////////////////////////////////////////
    // 1) Read the input image

	typedef itk::ImageFileReader< InputImageType >  ReaderType;
	ReaderType::Pointer reader = ReaderType::New();
	std::string readpath( argv[1] );
	readpath.append( argv[2] );
	reader->SetFileName( readpath );
	reader->Update();
	
    ////////////////////////////////////////////////
    // 2) Curvature anisotropic diffusion
	
	typedef itk::CurvatureAnisotropicDiffusionImageFilter< 
		InputImageType, InputImageType > SmoothingFilterType;
	SmoothingFilterType::Pointer smoothing = SmoothingFilterType::New();
	smoothing->SetTimeStep(0.04);
	smoothing->SetNumberOfIterations(5);
	smoothing->SetConductanceParameter(9.0);
	smoothing->SetInput( reader->GetOutput() );
	
    ////////////////////////////////////////////////
    // 3) Gradient magnitude recursive Gaussian
	
	const double sigma = atof(argv[8]);
	typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< 
		InputImageType, InputImageType > GradientFilterType;
	GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
	gradientMagnitude->SetSigma( sigma );
	gradientMagnitude->SetInput( smoothing->GetOutput() );
	
    ////////////////////////////////////////////////
    // 4) Sigmoid mapping
	
	const double K1 = atof(argv[9]);
	const double K2 = atof(argv[10]);
	typedef itk::SigmoidImageFilter< InputImageType, InputImageType > 
		SigmoidFilterType;
	SigmoidFilterType::Pointer sigmoid = SigmoidFilterType::New();
	sigmoid->SetOutputMinimum(0.0);
	sigmoid->SetOutputMaximum(1.0);
	sigmoid->SetAlpha( (K2 - K1)/6 );
	sigmoid->SetBeta( (K1 + K2)/2 );
	sigmoid->SetInput( gradientMagnitude->GetOutput() );
	
    ////////////////////////////////////////////////
    // 5) Segmentation with geodesic active contour
	
	typedef itk::FastMarchingImageFilter< InputImageType, InputImageType > 
		FastMarchingFilterType;
	FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New();
	
	typedef itk::GeodesicActiveContourLevelSetImageFilter< 
		InputImageType, InputImageType > GeodesicActiveContourFilterType;
	GeodesicActiveContourFilterType::Pointer geodesicActiveContour = 
		GeodesicActiveContourFilterType::New();
	
	const double propagation = atof( argv[11] );
	const double curvature = atof( argv[12] );
	const double advection = atof( argv[13] );
	const double iterations = atoi( argv[14] );
	geodesicActiveContour->SetPropagationScaling( propagation );
	geodesicActiveContour->SetCurvatureScaling( curvature );
	geodesicActiveContour->SetAdvectionScaling( advection );
	geodesicActiveContour->SetMaximumRMSError(0.01);
	geodesicActiveContour->SetNumberOfIterations( iterations );
	
	geodesicActiveContour->SetInput( fastMarching->GetOutput() );
	geodesicActiveContour->SetFeatureImage( sigmoid->GetOutput() );
	
    ////////////////////////////////////////////////
    // 6) Binary thresholding
	
	typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType > 
		ThresholdingFilterType;
	ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
	thresholder->SetLowerThreshold(-1000.0);
	thresholder->SetUpperThreshold(0.0);
	thresholder->SetOutsideValue(0);
	thresholder->SetInsideValue(255);
	thresholder->SetInput( geodesicActiveContour->GetOutput() );
	
    ////////////////////////////////////////////////
    // 7) Finish setting up fast marching
	
	typedef FastMarchingFilterType::NodeContainer NodeContainer;
	typedef FastMarchingFilterType::NodeType NodeType;
	
	NodeContainer::Pointer seeds = NodeContainer::New();
	InputImageType::IndexType seedPosition;
	seedPosition[0] = atoi( argv[4] );
	seedPosition[1] = atoi( argv[5] );
	seedPosition[2] = atoi( argv[6] );
	const double initialDistance = atof( argv[7] );
	const double seedValue = -initialDistance;
	NodeType node;
	node.SetValue( seedValue );
	node.SetIndex( seedPosition );
	seeds->Initialize();
	seeds->InsertElement(0, node);
	
	fastMarching->SetTrialPoints( seeds );
	fastMarching->SetSpeedConstant(1.0);
	fastMarching->SetOutputSize( reader->GetOutput()->GetBufferedRegion().GetSize() );
	fastMarching->SetOutputRegion( reader->GetOutput()->GetBufferedRegion() );
	fastMarching->SetOutputSpacing( reader->GetOutput()->GetSpacing() );
	fastMarching->SetOutputOrigin( reader->GetOutput()->GetOrigin() );
	
	////////////////////////////////////////////////
    // 7) Write output image
	
	typedef itk::ImageFileWriter< OutputImageType > WriterType;
	WriterType::Pointer writer = WriterType::New();
	std::string writepath( argv[1] );
	writepath.append( argv[3] );
	writer->SetFileName( writepath );
	writer->SetInput( thresholder->GetOutput() );
	
	try {
		writer->Update();
	}
	catch( itk::ExceptionObject &excep ) {
		std::cerr << "Exception caught!" << std::endl;
		std::cerr << excep << std::endl;
		return EXIT_FAILURE;
	}
	
	// The following writer is used to save the output of the sigmoid mapping
	typedef itk::ImageFileWriter< InputImageType > InternalWriterType;
	InternalWriterType::Pointer speedWriter = InternalWriterType::New();
	speedWriter->SetInput( sigmoid->GetOutput() );
	std::string sigmoidpath( argv[1] );
	speedWriter->SetFileName( sigmoidpath.append("SigmoidForGeodesic.mha"));
	speedWriter->Update();
	
	return 0;
}
Пример #10
0
void segment::Execute(int first,int last,double sig_min, double sig_max, double propagation, double curvature, double advection, double rms, int iterations, double alpha, double beta, double distance){
    ifstream myfile ("/home/gustavo/temp/endocardium.txt");
    for(int i =first; i<last;i++){
        typedef   float           InternalPixelType;
        const     unsigned int    Dimension = 2;

        typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;

        typedef unsigned char                            OutputPixelType;
        typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
        typedef itk::BinaryThresholdImageFilter<
                InternalImageType,
                OutputImageType    >       ThresholdingFilterType;
        ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
        thresholder->SetLowerThreshold( -1000.0 );
        thresholder->SetUpperThreshold(     0.0 );
        thresholder->SetOutsideValue(  0  );
        thresholder->SetInsideValue(  255 );

        typedef  itk::ImageFileReader< InternalImageType > ReaderType;
        typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;
        ReaderType::Pointer reader = ReaderType::New();
        WriterType::Pointer writer = WriterType::New();
        //WriterType::Pointer writer_out = WriterType::New();
        stringstream ss;

        string name = "/home/gustavo/temp/cine_";
        string type = ".tif";

        ss<<name<<(i+1)<<type;

        string filename = ss.str();
        ss.str("");

        reader->SetFileName(filename);
        reader->Update();

        InternalImageType::Pointer val = reader->GetOutput();

        typedef itk::RescaleIntensityImageFilter<
                InternalImageType,
                OutputImageType >   CastFilterType;

        typedef   itk::GradientMagnitudeRecursiveGaussianImageFilter<
                InternalImageType,
                InternalImageType >  GradientFilterType;
        typedef   itk::SigmoidImageFilter<
                InternalImageType,
                InternalImageType >  SigmoidFilterType;
        GradientFilterType::Pointer  gradientMagnitude = GradientFilterType::New();
        SigmoidFilterType::Pointer sigmoid = SigmoidFilterType::New();

        sigmoid->SetOutputMinimum(sig_min);
        sigmoid->SetOutputMaximum(sig_max);

        typedef  itk::FastMarchingImageFilter<
                InternalImageType,
                InternalImageType >    FastMarchingFilterType;

        FastMarchingFilterType::Pointer  fastMarching = FastMarchingFilterType::New();
        //const InternalImageType * inputImage = reader->GetOutput();
        const InternalImageType * inputImage = val;
        fastMarching->SetOutputRegion( inputImage->GetBufferedRegion() );
        fastMarching->SetOutputSpacing( inputImage->GetSpacing() );
        fastMarching->SetOutputOrigin( inputImage->GetOrigin() );
        fastMarching->SetOutputDirection( inputImage->GetDirection() );

        typedef  itk::GeodesicActiveContourLevelSetImageFilter< InternalImageType,
                InternalImageType >    GeodesicActiveContourFilterType;
        GeodesicActiveContourFilterType::Pointer geodesicActiveContour =
                GeodesicActiveContourFilterType::New();

        const double propagationScaling = propagation;
        //  Software Guide : BeginCodeSnippet
        geodesicActiveContour->SetPropagationScaling( propagationScaling );
        geodesicActiveContour->SetCurvatureScaling(curvature);
        geodesicActiveContour->SetAdvectionScaling(advection);

        geodesicActiveContour->SetMaximumRMSError(rms);
        geodesicActiveContour->SetNumberOfIterations(iterations);

        gradientMagnitude->SetInput(val);
        sigmoid->SetInput( gradientMagnitude->GetOutput() );
        geodesicActiveContour->SetInput(  fastMarching->GetOutput() );
        geodesicActiveContour->SetFeatureImage( sigmoid->GetOutput() );
        thresholder->SetInput( geodesicActiveContour->GetOutput() );
        //ImageOut = thresholder->GetOutput();
        //writer->SetInput( thresholder->GetOutput() );

        const double sigma = 0.5;
        gradientMagnitude->SetSigma(  sigma  );

        sigmoid->SetAlpha( alpha );
        sigmoid->SetBeta(  beta  );

        string line;
        int x;
        int y;

        if (myfile.is_open())
        {
            getline (myfile,line);
            string cmd = line;
            string arg;
            string::size_type pos = cmd.find(' ');
            if(cmd.npos != pos) {
                arg = cmd.substr(pos + 1);
                cmd = cmd.substr(0, pos);
            }
            x = atoi(cmd.c_str());
            y = atoi(arg.c_str());
        }

        typedef FastMarchingFilterType::NodeContainer  NodeContainer;
        typedef FastMarchingFilterType::NodeType       NodeType;
        NodeContainer::Pointer seeds = NodeContainer::New();
        InternalImageType::IndexType  seedPosition;
        seedPosition.SetElement(0,x);
        seedPosition.SetElement(1,y);
        //seedPosition.SetElement(2,(int)z);
        cout<<"X, Y = "<<x<<" "<<y<<endl;
        NodeType node;
        const double seedValue = - distance;
        node.SetValue( seedValue );
        node.SetIndex( seedPosition );

        seeds->Initialize();
        seeds->InsertElement( 0, node );

        fastMarching->SetTrialPoints(  seeds  );

        fastMarching->SetSpeedConstant( 4.0 );

        CastFilterType::Pointer caster2 = CastFilterType::New();
        CastFilterType::Pointer caster3 = CastFilterType::New();
        CastFilterType::Pointer caster4 = CastFilterType::New();
        WriterType::Pointer writer2 = WriterType::New();
        WriterType::Pointer writer3 = WriterType::New();
        WriterType::Pointer writer4 = WriterType::New();

        caster2->SetInput( gradientMagnitude->GetOutput() );
        writer2->SetInput( caster2->GetOutput() );
        writer2->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput2.tif");
        caster2->SetOutputMinimum(   0 );
        caster2->SetOutputMaximum( 255 );
        writer2->Update();
        caster3->SetInput( sigmoid->GetOutput() );
        writer3->SetInput( caster3->GetOutput() );
        writer3->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput3.tif");
        caster3->SetOutputMinimum(   0 );
        caster3->SetOutputMaximum( 255 );
        writer3->Update();
        caster4->SetInput( fastMarching->GetOutput() );
        writer4->SetInput( caster4->GetOutput() );
        writer4->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput4.tif");
        caster4->SetOutputMinimum(   0 );
        caster4->SetOutputMaximum( 255 );

        fastMarching->SetOutputSize(
                    reader->GetOutput()->GetBufferedRegion().GetSize() );
        reader->Update();

        stringstream ss2;

        string name2 = "/home/gustavo/temp/segmented_";
        string type2 = ".tif";

        if(i<9)
            ss2<<name2<<"00"<<(i+1)<<type2;
        if(i>=9 && i<99)
            ss2<<name2<<"0"<<(i+1)<<type2;
        if(i>=99)
            ss2<<name2<<(i+1)<<type2;
        string filename2 = ss2.str();
        ss2.str("");

        typedef itk::GradientMagnitudeImageFilter<OutputImageType, OutputImageType >  GradientType;
        GradientType::Pointer gradient = GradientType::New();
        gradient->SetInput(thresholder->GetOutput());
        gradient->Update();

        try
        {
            writer->SetFileName(filename2);
            writer->SetInput( gradient->GetOutput() );
            writer->Update();
        }
        catch( itk::ExceptionObject & excep )
        {
            std::cerr << "Exception caught !" << std::endl;
            std::cerr << excep << std::endl;
        }

        std::cout << std::endl;
        std::cout << "Max. no. iterations: " << geodesicActiveContour->GetNumberOfIterations() << std::endl;
        std::cout << "Max. RMS error: " << geodesicActiveContour->GetMaximumRMSError() << std::endl;
        std::cout << std::endl;
        std::cout << "No. elpased iterations: " << geodesicActiveContour->GetElapsedIterations() << std::endl;
        std::cout << "RMS change: " << geodesicActiveContour->GetRMSChange() << std::endl;
        writer4->Update();

        typedef itk::ImageFileWriter< InternalImageType > InternalWriterType;
        InternalWriterType::Pointer mapWriter = InternalWriterType::New();
        mapWriter->SetInput( fastMarching->GetOutput() );
        mapWriter->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput4.mha");
        mapWriter->Update();
        InternalWriterType::Pointer speedWriter = InternalWriterType::New();
        speedWriter->SetInput( sigmoid->GetOutput() );
        speedWriter->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput3.mha");
        speedWriter->Update();
        InternalWriterType::Pointer gradientWriter = InternalWriterType::New();
        gradientWriter->SetInput( gradientMagnitude->GetOutput() );
        gradientWriter->SetFileName("/home/gustavo/temp/GeodesicActiveContourImageFilterOutput2.mha");
        gradientWriter->Update();
    }
    myfile.close();

}
void gradient_calc(int S_i, float* S, int i, int j, int k, float* data, int r, int s,  int t, unsigned short* output_label){
	
	//cout<<"Starting Definitions..."<<endl;	
	//define the pixel and image types	
	typedef float PixelType;
	typedef itk::Image<PixelType, 3> ImageType;
	typedef itk::CovariantVector< double, 3 > GradientPixelType;
	typedef itk::Image< GradientPixelType, 3 > GradientImageType;
	typedef itk::GradientRecursiveGaussianImageFilter<ImageType, GradientImageType> GradientFilterType;
		
	//Initialize a new image which will read the input label	
	ImageType::Pointer image = ImageType::New();
	ImageType::IndexType start;
	start[0] = 0;
	start[1] = 0; 
	start[2] = 0;
	ImageType::SizeType size;
	size[0] = k;
	size[1] = j;
	size[2] = i;
	ImageType::SpacingType spacing;
	spacing[0] = S[0]; 
	spacing[1] = S[1]; 
	spacing[2] = S[2];
	//cout<<"X_space="<<spacing[0]<<", Y_space="<<spacing[1]<<", Z_space="<<spacing[2]<<endl;
	image->SetSpacing( spacing );
	ImageType::RegionType region;
	region.SetSize( size );
	region.SetIndex( start );
	image->SetRegions( region );
	image->Allocate();

	//Create an image iterator to copy the input label into the image file
	typedef itk::ImageRegionIterator< ImageType > IteratorType;
	IteratorType it( image, image->GetRequestedRegion() );

	int count = 0;	
	while(!it.IsAtEnd()){	
		it.Set( data[ count ] );
		++it;
		count++;
	}
	
	//Calculate the vector gradient of the image
	GradientFilterType::Pointer gradientMapFilter = GradientFilterType::New();
	gradientMapFilter->SetInput( image );
	gradientMapFilter->SetSigma( 1.0 );
	gradientMapFilter->Update();

	//Creates a new image and iterator of the gradient
	GradientImageType::Pointer image2 = gradientMapFilter->GetOutput();
	typedef itk::ImageRegionConstIterator< GradientImageType > IteratorType2;
	IteratorType2 it2( image2, image2->GetRequestedRegion() );
	//ImageType::IndexType idx = it2.GetIndex();

	//Outputs the input image to test if the input worked correctly
	ImageType::RegionType region2 = image2->GetLargestPossibleRegion();

	long int count2 = 0;	
	while(!it2.IsAtEnd()){
	//while(count2 < (r * s * t - 1)){		
		float magnitude = sqrt(it2.Get()[0] * it2.Get()[0] + it2.Get()[1] * it2.Get()[1] + it2.Get()[2] * it2.Get()[2]);
		output_label[ count2 ] = magnitude ;
		count2++;
		++it2;

	}
	
}