Example #1
0
FuzzyCMeans::FuzzyCMeans(QVector<ClusterPoint2D> &points, QVector<ClusterCentroid2D> &clusters, float fuzzy, imageType::Pointer myImage, int numCluster)
{
    this->Eps = std::pow(10, -5);
        this->isConverged=false;
        this->Points = points;
        this->Clusters = clusters;
        this->myImageHeight = myImage->GetBufferedRegion().GetSize()[0];
        this->myImageWidth = myImage->GetBufferedRegion().GetSize()[1];
        this->myImage = myImage;
        U= boost::numeric::ublas::matrix<double>(Points.size(),Clusters.size());
        this->Fuzzyness = fuzzy;

        double diff;


        imageType::SizeType size;
        size[0]=myImageWidth; // x axis
        size[1]=myImageHeight; // y
        imageType::RegionType region;
        region.SetSize(size);
        imageType::Pointer image = imageType::New();
        image->SetRegions(region);
        image->Allocate(); // immagine create

        // Iterate through all points to create initial U matrix
        for (int i = 0; i < Points.size()-1; i++)
        {
            ClusterPoint2D p = Points.at(i);
            double sum = 0.0;

            for (int j = 0; j < Clusters.size()-1; j++)
            {
                ClusterCentroid2D c = Clusters.at(j);
                diff = std::sqrt(std::pow(CalculateEuclideanDistance(p, c), 2.0));
                //U(i, j) = (diff == 0) ? Eps : diff;
                if (diff==0){
                    U(i,j)=Eps;
                }
                else{
                    U(i,j)=diff;
                }
                sum += U(i, j);
            }
         }

        this->RecalculateClusterMembershipValues();
}
// ------------------------------------------------------------------------
InitialTransformExtractor::TranslationType InitialTransformExtractor::ComputeTranslation(
    const ImageType::Pointer &image,
    const OptionsData &options)
{
    // set the offsets
    TranslationType translation;
    translation.Fill(0);
    translation[0] -= options.roiOffset[0];
    translation[1] -= options.roiOffset[1];
    translation[2] -= options.roiOffset[2];


    ImageType::PointType origin = image->GetOrigin();
    translation[0] -= origin[0];
    translation[1] -= origin[1];
    translation[2] -= origin[2];

    return translation;
}
Example #3
0
void TestDeepCopyUnsignedCharScalar()
{
  itk::Index<2> corner = {{0,0}};
  itk::Size<2> size = {{10,10}};
  itk::ImageRegion<2> region(corner, size);

  typedef itk::Image<unsigned char, 2> ImageType;
  ImageType::Pointer imageIn = ImageType::New();
  imageIn->SetRegions(region);
  imageIn->Allocate();

  ImageType::Pointer imageOut = ImageType::New();
  ITKHelpers::DeepCopy(imageIn.GetPointer(), imageOut.GetPointer());
}
Example #4
0
void TestBlurAllChannels()
{

  {
  typedef itk::VectorImage<float, 2> ImageType;
  ImageType::Pointer image = ImageType::New();
  ImageType::Pointer blurred = ImageType::New();

  float sigma = 2.0f;
  ITKHelpers::BlurAllChannels(image.GetPointer(), blurred.GetPointer(), sigma);
  }

  {
  typedef itk::VectorImage<float, 2> ImageType;
  ImageType::Pointer image = ImageType::New();
  ImageType::Pointer blurred = ImageType::New();

  float sigma = 2.0f;
  ITKHelpers::BlurAllChannels(image.GetPointer(), blurred.GetPointer(), sigma);
  }

}
// ------------------------------------------------------------------------
void OpenCVValve::ConvertImage(const ImageType::Pointer &input, MatPtr &mat)
{
	// cast the image to uchar 
	typedef itk::Image<unsigned char, 2> OutputImageType;
	typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType> CasterType;
	CasterType::Pointer caster = CasterType::New();
	caster->SetOutputMaximum(255);
	caster->SetOutputMinimum(0);
	caster->SetInput(input);
	caster->Update();


	OutputImageType::Pointer output = caster->GetOutput();


	typedef itk::ImageFileWriter<OutputImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetImageIO(itk::PNGImageIO::New());
	writer->SetInput(output);
	writer->SetFileName("test.png");
	writer->Update();



	ImageType::SizeType size = input->GetLargestPossibleRegion().GetSize();
	unsigned int rows = size[1];
	unsigned int cols = size[0];

	mat = new MatType(rows,cols, CV_8UC1);


	itk::ImageRegionConstIterator<OutputImageType> it(output, output->GetLargestPossibleRegion());
	it.GoToBegin();
	while(!it.IsAtEnd())
	{
		OutputImageType::IndexType index = it.GetIndex();
		unsigned char val = it.Get();
		mat->at<unsigned char>(cv::Point(index[0], index[1])) = val;
		++it;
	}
}
Example #6
0
void TestUpsample()
{
  typedef itk::Image<unsigned char, 2> ImageType;
  ImageType::Pointer image = ImageType::New();

  itk::Index<2> corner = {{0,0}};
  itk::Size<2> size = {{100,100}};
  itk::ImageRegion<2> region(corner, size);

  image->SetRegions(region);
  image->Allocate();

  ImageType::Pointer upsampled = ImageType::New();

  ITKHelpers::Upsample(image.GetPointer(), 2, upsampled.GetPointer());

  std::cout << "TestUpsample() output size: "
            << upsampled->GetLargestPossibleRegion().GetSize() << std::endl;
}
bool VolumeProcess:: RunFillingZeroOnBouandary(int Bx,int By,int Bz)
{
	ImageType::Pointer tempImg = ImageType::New();
	tempImg->SetRegions( m_outputImage->GetLargestPossibleRegion() );
	tempImg->Allocate();
	tempImg->FillBuffer(0);

	ImageType::RegionType fullRegion = m_outputImage->GetBufferedRegion();

	int numColumns = fullRegion.GetSize(0);
	int numRows = fullRegion.GetSize(1);
	int numStacks = fullRegion.GetSize(2);
	int i, j,k; 

	itk::ImageRegionIteratorWithIndex< ImageType > itr( m_outputImage, fullRegion );

	for(itr.GoToBegin(); !itr.IsAtEnd(); ++itr)
	{
		
		ImageType::IndexType index = itr.GetIndex();
	    ImageType::PixelType pix = m_outputImage->GetPixel(index);
        i = index[0];
		j = index[1];
		k = index[2];
		if (i < Bx || i > numColumns -Bx || j < By || j > numRows-By ||k <Bz ||k > numStacks-Bz )
		    tempImg->SetPixel(itr.GetIndex(), 0);
		else 
			tempImg->SetPixel(itr.GetIndex(), pix);
     }
		//Copy temp img back to image 
	itk::ImageRegionIterator< ImageType > itr1( tempImg, tempImg->GetLargestPossibleRegion());
	itk::ImageRegionIterator< ImageType > itr2( m_outputImage, m_outputImage->GetLargestPossibleRegion());
	for(itr1.GoToBegin(), itr2.GoToBegin() ; !itr1.IsAtEnd(); ++itr1, ++itr2)
	{
	  itr2.Set( itr1.Get() );
	}

	if(debug)
		std::cerr << "RunFillingZero Done" << std::endl;

	return true;
  
}
  void setUp(void)
  {
    // Load Image Data
    m_Image = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer());
    mitk::CastToItkImage(m_Image,m_ItkImage);

    // Create a single mask with only one pixel within the regions
    mitk::Image::Pointer mask1 = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer());
    mitk::CastToItkImage(mask1,m_ItkMask);
    m_ItkMask->FillBuffer(0);
    MaskType::IndexType index;
    index[0]=88;index[1]=81;index[2]=13;
    m_ItkMask->SetPixel(index, 1);
    MITK_INFO << "Pixel Value: "<<m_ItkImage->GetPixel(index);
    mitk::CastToMitkImage(m_ItkMask, m_Mask);

    // Create a mask with a covered region
    mitk::Image::Pointer lmask1 = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer());
    mitk::CastToItkImage(lmask1,m_ItkMask1);
    m_ItkMask1->FillBuffer(0);
    int range=2;
    for (int x = 88-range;x < 88+range+1;++x)
    {
      for (int y=81-range;y<81+range+1;++y)
      {
        for (int z=13-range;z<13+range+1;++z)
        {
          index[0] = x;
          index[1] = y;
          index[2] = z;
          //MITK_INFO << "Pixel: " <<m_ItkImage->GetPixel(index);
          m_ItkMask1->SetPixel(index, 1);
        }
      }
    }
    mitk::CastToMitkImage(m_ItkMask1, m_Mask1);

    m_GradientImage=GenerateGradientWithDimXImage<unsigned char>(5,5,5);
    m_GradientMask = GenerateMaskImage<unsigned char>(5,5,5);
  }
Example #9
0
bool TestDeepCopyFloatScalar()
{
  itk::Index<2> corner = {{0,0}};
  itk::Size<2> size = {{10,10}};
  itk::ImageRegion<2> region(corner, size);

  typedef itk::Image<float, 2> ImageType;
  ImageType::Pointer imageIn = ImageType::New();
  imageIn->SetRegions(region);
  imageIn->Allocate();

  ImageType::Pointer imageOut = ImageType::New();
  ITKHelpers::DeepCopy(imageIn.GetPointer(), imageOut.GetPointer());

  return true;
}
Example #10
0
bool TestRandomImage()
{
  typedef itk::Image<unsigned char, 2> ImageType;
  ImageType::Pointer image = ImageType::New();

  itk::Index<2> corner = {{0,0}};
  itk::Size<2> size = {{100,100}};
  itk::ImageRegion<2> region(corner, size);

  image->SetRegions(region);
  image->Allocate();
  image->FillBuffer(0);

  ITKHelpers::RandomImage(image.GetPointer());
  ITKHelpers::WriteImage(image.GetPointer(), "random.png");

  return true;
}
Example #11
0
void TestDrawRectangle()
{
  typedef itk::Image<unsigned char, 2> ImageType;
  ImageType::Pointer image = ImageType::New();

  itk::Index<2> corner = {{0,0}};
  itk::Size<2> size = {{100,100}};
  itk::ImageRegion<2> region(corner, size);

  image->SetRegions(region);
  image->Allocate();
  image->FillBuffer(0);

  itk::Index<2> corner0 = {{10,10}};
  itk::Index<2> corner1 = {{30,30}};
  ITKHelpers::DrawRectangle(image.GetPointer(), 255,
                            corner0, corner1);

  ITKHelpers::WriteImage(image.GetPointer(), "rectangle.png");
}
Example #12
0
bool TestComputeGradientsInRegion()
{
  itk::Index<2> imageCorner = {{0,0}};
  itk::Size<2> imageSize = {{100,100}};
  itk::ImageRegion<2> imageRegion(imageCorner, imageSize);

  typedef itk::Image<unsigned char, 2> ImageType;
  ImageType::Pointer image = ImageType::New();
  image->SetRegions(imageRegion);
  image->Allocate();

  itk::ImageRegionIterator<ImageType> imageIterator(image, image->GetLargestPossibleRegion());

  while(!imageIterator.IsAtEnd())
  {
    imageIterator.Set(rand() % 255);

    ++imageIterator;
  }

  ITKHelpers::WriteImage(image.GetPointer(), "Image.mha");

  itk::Index<2> regionCorner = {{50,50}};
  itk::Size<2> regionSize = {{10,10}};
  itk::ImageRegion<2> region(regionCorner, regionSize);

  typedef itk::Image<itk::CovariantVector<float, 2>, 2> GradientImageType;
  GradientImageType::Pointer gradientImage = GradientImageType::New();

  std::cout << "Computing gradients..." << std::endl;
  ITKHelpers::ComputeGradientsInRegion(image.GetPointer(), region, gradientImage.GetPointer());

  std::cout << "Writing..." << std::endl;
  ITKHelpers::WriteImage(gradientImage.GetPointer(), "GradientImage.mha");

  return true;
}
// Run with: Data/trashcan.mha Data/trashcan_mask.mha 15 Data/trashcan.vtp Intensity filled.mha
int main(int argc, char *argv[])
{
  // Verify arguments
  if(argc != 6)
    {
    std::cerr << "Required arguments: image.mha imageMask.mha patch_half_width normals.vts output.mha" << std::endl;
    std::cerr << "Input arguments: ";
    for(int i = 1; i < argc; ++i)
      {
      std::cerr << argv[i] << " ";
      }
    return EXIT_FAILURE;
    }

  // Parse arguments
  std::string imageFilename = argv[1];
  std::string maskFilename = argv[2];

  std::stringstream ssPatchRadius;
  ssPatchRadius << argv[3];
  unsigned int patch_half_width = 0;
  ssPatchRadius >> patch_half_width;

  std::string normalsFileName = argv[4];

  std::string outputFilename = argv[5];

  // Output arguments
  std::cout << "Reading image: " << imageFilename << std::endl;
  std::cout << "Reading mask: " << maskFilename << std::endl;
  std::cout << "Patch half width: " << patch_half_width << std::endl;
  std::cout << "Reading normals: " << normalsFileName << std::endl;
  std::cout << "Output: " << outputFilename << std::endl;

  vtkSmartPointer<vtkXMLStructuredGridReader> structuredGridReader = vtkSmartPointer<vtkXMLStructuredGridReader>::New();
  structuredGridReader->SetFileName(normalsFileName.c_str());
  structuredGridReader->Update();
  
  typedef FloatVectorImageType ImageType;

  typedef  itk::ImageFileReader<ImageType> ImageReaderType;
  ImageReaderType::Pointer imageReader = ImageReaderType::New();
  imageReader->SetFileName(imageFilename);
  imageReader->Update();

  ImageType::Pointer image = ImageType::New();
  ITKHelpers::DeepCopy(imageReader->GetOutput(), image.GetPointer());

  Mask::Pointer mask = Mask::New();
  mask->Read(maskFilename);

  std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl;
  std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl;

  typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType;
  typedef FeatureVectorPixelDescriptor FeatureVectorPixelDescriptorType;

  // Create the graph
  typedef boost::grid_graph<2> VertexListGraphType;
  boost::array<std::size_t, 2> graphSideLengths = { { imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0],
                                                      imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] } };
  VertexListGraphType graph(graphSideLengths);
  typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType;

  // Get the index map
  typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType;
  IndexMapType indexMap(get(boost::vertex_index, graph));

  // Create the priority map
  typedef boost::vector_property_map<float, IndexMapType> PriorityMapType;
  PriorityMapType priorityMap(num_vertices(graph), indexMap);

  // Create the node fill status map. Each pixel is either filled (true) or not filled (false).
  typedef boost::vector_property_map<bool, IndexMapType> FillStatusMapType;
  FillStatusMapType fillStatusMap(num_vertices(graph), indexMap);

  // Create the boundary status map. A node is on the current boundary if this property is true. 
  // This property helps the boundaryNodeQueue because we can mark here if a node has become no longer
  // part of the boundary, so when the queue is popped we can check this property to see if it should
  // actually be processed.
  typedef boost::vector_property_map<bool, IndexMapType> BoundaryStatusMapType;
  BoundaryStatusMapType boundaryStatusMap(num_vertices(graph), indexMap);

  // Create the descriptor map. This is where the data for each pixel is stored.
  typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType;
  ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap);

  // Create the descriptor map. This is where the data for each pixel is stored.
  typedef boost::vector_property_map<FeatureVectorPixelDescriptorType, IndexMapType> FeatureVectorDescriptorMapType;
  FeatureVectorDescriptorMapType featureVectorDescriptorMap(num_vertices(graph), indexMap);

  // Create the patch inpainter. The inpainter needs to know the status of each pixel to determine if they should be inpainted.
  typedef MaskedGridPatchInpainter<FillStatusMapType> InpainterType;
  InpainterType patchInpainter(patch_half_width, fillStatusMap);

  // Create the priority function
  typedef PriorityRandom PriorityType;
  PriorityType priorityFunction;

  // Create the boundary node queue. The priority of each node is used to order the queue.
  typedef boost::vector_property_map<std::size_t, IndexMapType> IndexInHeapMap;
  IndexInHeapMap index_in_heap(indexMap);

  // Create the priority compare functor
  typedef std::less<float> PriorityCompareType;
  PriorityCompareType lessThanFunctor;

  typedef boost::d_ary_heap_indirect<VertexDescriptorType, 4, IndexInHeapMap, PriorityMapType, PriorityCompareType> BoundaryNodeQueueType;
  BoundaryNodeQueueType boundaryNodeQueue(priorityMap, index_in_heap, lessThanFunctor);

  // Create the descriptor visitors
  typedef FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitor<VertexListGraphType, FeatureVectorDescriptorMapType> FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType;
  FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor(featureVectorDescriptorMap, structuredGridReader->GetOutput());

  typedef ImagePatchDescriptorVisitor<VertexListGraphType, ImageType, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType;
  ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(image, mask, imagePatchDescriptorMap, patch_half_width);

  typedef CompositeDescriptorVisitor<VertexListGraphType> CompositeDescriptorVisitorType;
  CompositeDescriptorVisitorType compositeDescriptorVisitor;
  compositeDescriptorVisitor.AddVisitor(&imagePatchDescriptorVisitor);
  compositeDescriptorVisitor.AddVisitor(&featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor);

  // Create the inpainting visitor
  typedef InpaintingVisitor<VertexListGraphType, ImageType, BoundaryNodeQueueType, FillStatusMapType,
                            CompositeDescriptorVisitorType, PriorityType, PriorityMapType, BoundaryStatusMapType> InpaintingVisitorType;
  InpaintingVisitorType inpaintingVisitor(image, mask, boundaryNodeQueue, fillStatusMap,
                                          compositeDescriptorVisitor, priorityMap, &priorityFunction, patch_half_width, boundaryStatusMap);

  InitializePriority(mask, boundaryNodeQueue, priorityMap, &priorityFunction, boundaryStatusMap);

  // Initialize the boundary node queue from the user provided mask image.
  InitializeFromMaskImage(mask, &inpaintingVisitor, graph, fillStatusMap);
  std::cout << "PatchBasedInpaintingNonInteractive: There are " << boundaryNodeQueue.size()
            << " nodes in the boundaryNodeQueue" << std::endl;

  // Create the nearest neighbor finder
//   typedef LinearSearchKNNProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> KNNSearchType;
//   KNNSearchType linearSearchKNN(featureVectorDescriptorMap);
  typedef LinearSearchCriteriaProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> ThresholdSearchType;
  //float maximumAngle = 0.34906585; // ~ 20 degrees
  float maximumAngle = 0.15; // ~ 10 degrees
  //float maximumAngle = 0.08; // ~ 5 degrees (this seems to be too strict)
  ThresholdSearchType thresholdSearchType(featureVectorDescriptorMap, maximumAngle);

  typedef LinearSearchBestProperty<ImagePatchDescriptorMapType, ImagePatchDifference<ImagePatchPixelDescriptorType> > BestSearchType;
  BestSearchType linearSearchBest(imagePatchDescriptorMap);

  TwoStepNearestNeighbor<ThresholdSearchType, BestSearchType> twoStepNearestNeighbor(thresholdSearchType, linearSearchBest);

  // Perform the inpainting
  std::cout << "Performing inpainting...: " << std::endl;
  inpainting_loop(graph, inpaintingVisitor, boundaryStatusMap, boundaryNodeQueue, twoStepNearestNeighbor, patchInpainter);

  HelpersOutput::WriteImage<ImageType>(image, outputFilename);

  return EXIT_SUCCESS;
}
Example #14
0
int
main(int argc, char* argv[])
{
	boost::filesystem::path inputFile;
	boost::filesystem::path outputFile;

	Algorithm algorithm;
	std::string algorithmName;

	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("input,i", po::value<boost::filesystem::path>(&inputFile), "input file")
		("algorithm,a", po::value<std::string>(&algorithmName)->default_value("itk-implementation"), "itk-implementation")
		("output,o", po::value<boost::filesystem::path>(&outputFile), "output mask file")
		;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	algorithm = getAlgorithmFromString(algorithmName);

	if (vm.count("help")) {
		std::cout << desc << "\n";
		return 1;
	}

	if (vm.count("input") == 0) {
		std::cout << "Missing input filename\n" << desc << "\n";
		return 1;
	}

	if (vm.count("output") == 0) {
		std::cout << "Missing output filename\n" << desc << "\n";
		return 1;
	}

	typedef itk::ImageFileReader<ImageType>  ImageReaderType;

	BOOST_LOG_TRIVIAL(info) << "Loading inputs ...";
	ImageReaderType::Pointer imageReader = ImageReaderType::New();
	imageReader->SetFileName(inputFile.string());
	imageReader->Update();

	ImageType::Pointer image = imageReader->GetOutput();

	LabeledImageType::Pointer outputImage;

	switch (algorithm) {
	case Algorithm::ItkImplementation: {
		BOOST_LOG_TRIVIAL(info) << "Running ITK version of watershed transformation ...";
			WatershedFilterType::Pointer filter = WatershedFilterType::New();
			filter->SetInput(image);
			filter->MarkWatershedLineOff();

			boost::timer::cpu_timer computationTimer;
			computationTimer.start();
			filter->Update();
			BOOST_LOG_TRIVIAL(info) << "Computation time: " << computationTimer.format(9, "%w");

			outputImage = filter->GetOutput();
		}
		break;
	default:
		BOOST_LOG_TRIVIAL(info) << "Allocating output ...";
		outputImage = LabeledImageType::New();
		outputImage->SetRegions(image->GetLargestPossibleRegion());
		outputImage->Allocate();
		outputImage->SetSpacing(image->GetSpacing());
		BOOST_LOG_TRIVIAL(info) << "Running CUDA version of watershed transformation (topographical distance)...";
		boost::timer::cpu_timer computationTimer;
		computationTimer.start();
		watershedTransformation2(
			cugip::const_view(*(image.GetPointer())),
			cugip::view(*(outputImage.GetPointer())),
			Options()
			);
		BOOST_LOG_TRIVIAL(info) << "Computation time: " << computationTimer.format(9, "%w");
		//BOOST_LOG_TRIVIAL(error) << "Unknown algorithm";
	}

	BOOST_LOG_TRIVIAL(info) << "Saving output `" << outputFile << "` ...";
	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName(outputFile.string());
	writer->SetInput(outputImage);
	try {
		writer->Update();
	} catch (itk::ExceptionObject & error) {
		std::cerr << "Error: " << error << std::endl;
		return EXIT_FAILURE;
	}

	return 0;
}
void LabelsVolumeGenerator::postProcessTargetITK()
{
    typedef unsigned char       PixelType;
    typedef Image<PixelType, 3> ImageType;

    // create a new image from the target data

    ImageType::Pointer input = ImageType::New();

    ImageType::IndexType start;
    start.Fill(0);

    ImageType::SizeType size;
    for (int i = 0; i < 3; ++i) size[i] = m_targetVolume->dimensions[i];

    ImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(start);

    input->SetRegions(region);
    input->SetSpacing(m_targetVolume->spacing.data());
    input->Allocate();

    memcpy(input->GetBufferPointer(), m_targetVolume->data, m_bufferSize);

    // create a grayscale dilation filter and a structuring element

    typedef BinaryBallStructuringElement<PixelType, 3> StructureType;
    typedef GrayscaleDilateImageFilter<ImageType, ImageType, StructureType> DilateFilterType;

    DilateFilterType::Pointer filter = DilateFilterType::New();

    StructureType structure;
    structure.SetRadius(1);

    filter->SetKernel(structure);

    // set up progress reporting
    if (m_progressReporter)
    {
        CStyleCommand::Pointer command = CStyleCommand::New();
        command->SetClientData(m_progressReporter);
        command->SetCallback(ProgressCallback);
        filter->AddObserver(ProgressEvent(), command);
        m_progressReporter->start("Post-Processing Label volume",
                                  "Dilating label field...");
    }

    // hook up the filters and run

    filter->SetInput(input);
    filter->Update();

    if (m_progressReporter)
        m_progressReporter->finish();

    // copy back into the target volume data
    memcpy(m_targetVolume->data, filter->GetOutput()->GetBufferPointer(), m_bufferSize);

    // threshold and gaussian blur to put a smooth version into the alpha channel

    typedef BinaryThresholdImageFilter<ImageType, ImageType> ThresholderType;
//    typedef DiscreteGaussianImageFilter<ImageType, ImageType> SmoothFilterType;
    typedef SmoothingRecursiveGaussianImageFilter<ImageType, ImageType> SmoothFilterType;

    ThresholderType::Pointer thresholder = ThresholderType::New();
    thresholder->SetLowerThreshold(1);
    thresholder->SetUpperThreshold(255);
    thresholder->SetInsideValue(255);
    thresholder->SetOutsideValue(0);

    SmoothFilterType::Pointer smoother = SmoothFilterType::New();
//    smoother->SetVariance(0.05); // in physical units
//    smoother->SetMaximumKernelWidth(5);
    smoother->SetSigma(0.2);

    // set up progress reporting (again)
    if (m_progressReporter)
    {
        CStyleCommand::Pointer command = CStyleCommand::New();
        command->SetClientData(m_progressReporter);
        command->SetCallback(ProgressCallback);
        smoother->AddObserver(ProgressEvent(), command);
        m_progressReporter->start("Post-Processing Label volume",
                                  "Smoothing alpha mask...");
    }

    // hook up the filters and run

    thresholder->SetInput(input);
    smoother->SetInput(thresholder->GetOutput());
    smoother->Update();

    // copy back into the target volume data
    memcpy(m_targetMask->data, smoother->GetOutput()->GetBufferPointer(), m_bufferSize);

    if (m_progressReporter)
        m_progressReporter->finish();
}
Example #16
0
int main( int argc, char* argv[] )
{
	std::string input_file;
	std::string output_file;
	float variance;
	int patchRadius;
	int searchRadius;
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("input,i", po::value<std::string>(&input_file), "input file")
		("output,o", po::value<std::string>(&output_file), "output file")
		("variance,v", po::value<float>(&variance)->default_value(10.0), "variance")
		("patch-radius,p", po::value<int>(&patchRadius)->default_value(2), "patch radius")
		("search-radius,s", po::value<int>(&searchRadius)->default_value(4), "search radius")
		;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	if (vm.count("help")) {
	    std::cout << desc << "\n";
	    return 1;
	}

	if (vm.count("input") == 0) {
	    std::cout << "Missing input filename\n" << desc << "\n";
	    return 1;
	}

	if (vm.count("output") == 0) {
	    std::cout << "Missing output filename\n" << desc << "\n";
	    return 1;
	}


	const unsigned int Dimension = 3;

	//typedef float                              PixelType;
	//typedef itk::Image< PixelType, Dimension > ImageType;

	typedef itk::ImageFileReader<ImageType>  ReaderType;
	typedef itk::ImageFileWriter<ImageType> WriterType;

	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(input_file);
	reader->Update();

	ImageType::Pointer image = reader->GetOutput();

	ImageType::Pointer output_image = ImageType::New();
	output_image->SetRegions(image->GetLargestPossibleRegion());
	output_image->Allocate();
	output_image->SetSpacing(image->GetSpacing());

	//denoise(image, output_image);
	denoise(
		image->GetPixelContainer()->GetBufferPointer(),
		output_image->GetPixelContainer()->GetBufferPointer(),
		image->GetLargestPossibleRegion().GetSize()[0],
		image->GetLargestPossibleRegion().GetSize()[1],
		image->GetLargestPossibleRegion().GetSize()[2],
		variance,
		patchRadius,
		searchRadius);


	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName(output_file);
	writer->SetInput(output_image);

	try
	{
		writer->Update();
	}
	catch( itk::ExceptionObject & error )
	{
		std::cerr << "Error: " << error << std::endl;
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Example #17
0
int main(int argc, char ** argv){

	typedef itk::Image<float,3> ImageType;

	typedef itk::ImageFileReader<ImageType> ReaderType;

	typedef itk::ImageFileWriter<ImageType> WriterType;

	ReaderType::Pointer reader = ReaderType::New();

	reader->SetFileName(argv[1]);

	typedef itk::HessianRecursiveGaussianImageFilter<ImageType> HessianFilterType;
	typedef HessianFilterType::OutputImageType HessianImageType;
	typedef HessianImageType::PixelType HessianType;

	HessianFilterType::Pointer hessianFilter = HessianFilterType::New();

	hessianFilter->SetSigma(0.05);
	hessianFilter->SetInput(reader->GetOutput());

	hessianFilter->Update();

	HessianImageType::Pointer hessianImage = hessianFilter->GetOutput();
	hessianImage->DisconnectPipeline();

	typedef itk::ImageRegionConstIteratorWithIndex<HessianImageType> IteratorType;

	IteratorType hessianIterator(hessianImage,hessianImage->GetLargestPossibleRegion());

	typedef HessianType::EigenValuesArrayType EigenvalueArrayType;
	EigenvalueArrayType expectation;
	expectation.Fill(0.0);
	unsigned count=0;

	ImageType::Pointer small = ImageType::New();
	small->CopyInformation(reader->GetOutput());

	small->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
	small->Allocate();
	small->FillBuffer(0.0);
	ImageType::Pointer medium = ImageType::New();
	medium->CopyInformation(reader->GetOutput());
	medium->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());

	medium->Allocate();
	medium->FillBuffer(0.0);
	ImageType::Pointer large = ImageType::New();
	large->CopyInformation(reader->GetOutput());
	large->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
	large->Allocate();
	large->FillBuffer(0.0);

	while(!hessianIterator.IsAtEnd()){

		auto hessian = hessianIterator.Get();
		EigenvalueArrayType eigenValues;
		hessian.ComputeEigenValues(eigenValues);

		std::sort(eigenValues.Begin(),eigenValues.End(),[](double & a, double &b){
			return std::abs(a) > std::abs(b);
		});

		//std::cout << eigenValues[0] << "\t"<< eigenValues[1] << "\t" << eigenValues[2] <<std::endl;

		if(eigenValues[0]<0){
			expectation[0]+=eigenValues[0];
			expectation[1]+=eigenValues[1];
			expectation[2]+=eigenValues[2];

			count++;

			large->SetPixel(hessianIterator.GetIndex(),std::abs(eigenValues[0]));
			medium->SetPixel(hessianIterator.GetIndex(),std::abs(eigenValues[1]));
			small->SetPixel(hessianIterator.GetIndex(),std::abs(eigenValues[2]));
		}
		++hessianIterator;
	}
	expectation[0]=expectation[0]/count;
	expectation[1]=expectation[1]/count;
	expectation[2]=expectation[2]/count;

	WriterType::Pointer smallWriter = WriterType::New();
	smallWriter->SetInput(small);
	smallWriter->SetFileName("small.mha");
	smallWriter->Update();

	WriterType::Pointer mediumWriter = WriterType::New();
	mediumWriter->SetInput(medium);
	mediumWriter->SetFileName("medium.mha");
	mediumWriter->Update();

	WriterType::Pointer largeWriter = WriterType::New();
	largeWriter->SetInput(large);
	largeWriter->SetFileName("large.mha");
	largeWriter->Update();

	std::cout << "Expectation: \t" << expectation<< std::endl;

}
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();
}
Example #19
0
int main(int argc, char *argv[])
{
	/* % MINIMALPATH Recherche du chemin minimum de Haut vers le bas et de
	% bas vers le haut tel que dÈcrit par Luc Vincent 1998
	% [sR,sC,S] = MinimalPath(I,factx)
	%
	%   I     : Image d'entrÔøΩe dans laquelle on doit trouver le
	%           chemin minimal
	%   factx : Poids de linearite [1 10]
	%
	% Programme par : Ramnada Chav
	% ModifiÈ le 16 novembre 2007 */

	    typedef itk::ImageDuplicator< ImageType > DuplicatorType3D;
	    typedef itk::InvertIntensityImageFilter <ImageType> InvertIntensityImageFilterType;
	    typedef itk::StatisticsImageFilter<ImageType> StatisticsImageFilterType;

	    ImageType::Pointer inverted_image = image;

//	    if (invert)
//	    {
//	        StatisticsImageFilterType::Pointer statisticsImageFilterInput = StatisticsImageFilterType::New();
//	        statisticsImageFilterInput->SetInput(image);
//	        statisticsImageFilterInput->Update();
//	        double maxIm = statisticsImageFilterInput->GetMaximum();
//	        InvertIntensityImageFilterType::Pointer invertIntensityFilter = InvertIntensityImageFilterType::New();
//	        invertIntensityFilter->SetInput(image);
//	        invertIntensityFilter->SetMaximum(maxIm);
//	        invertIntensityFilter->Update();
//	        inverted_image = invertIntensityFilter->GetOutput();
//	    }


	    ImageType::SizeType sizeImage = image->GetLargestPossibleRegion().GetSize();
	    int m = sizeImage[0]; // x to change because we are in AIL
	    int n = sizeImage[2]; // y
	    int p = sizeImage[1]; // z

	    // create image with high values J1
	    DuplicatorType3D::Pointer duplicator = DuplicatorType3D::New();
	    duplicator->SetInputImage(inverted_image);
	    duplicator->Update();
	    ImageType::Pointer J1 = duplicator->GetOutput();
	    typedef itk::ImageRegionIterator<ImageType> ImageIterator3D;
	    ImageIterator3D vItJ1( J1, J1->GetBufferedRegion() );
	    vItJ1.GoToBegin();
	    while ( !vItJ1.IsAtEnd() )
	    {
	        vItJ1.Set(100000000);
	        ++vItJ1;
	    }

	    // create image with high values J2
	    DuplicatorType3D::Pointer duplicatorJ2 = DuplicatorType3D::New();
	    duplicatorJ2->SetInputImage(inverted_image);
	    duplicatorJ2->Update();
	    ImageType::Pointer J2 = duplicatorJ2->GetOutput();
	    ImageIterator3D vItJ2( J2, J2->GetBufferedRegion() );
	    vItJ2.GoToBegin();
	    while ( !vItJ2.IsAtEnd() )
	    {
	        vItJ2.Set(100000000);
	        ++vItJ2;
	    }

	    DuplicatorType3D::Pointer duplicatorCPixel = DuplicatorType3D::New();
	    duplicatorCPixel->SetInputImage(inverted_image);
	    duplicatorCPixel->Update();
	    ImageType::Pointer cPixel = duplicatorCPixel->GetOutput();

	    ImageType::IndexType index;

	    // iterate on slice from slice 1 (start=0) to slice p-2. Basically, we avoid first and last slices.
	    // IMPORTANT: first slice of J1 and last slice of J2 must be set to 0...
	    for (int x=0; x<m; x++)
	    {
	        for (int y=0; y<n; y++)
	        {
	            index[0] = x; index[1] = 0; index[2] = y;
	            J1->SetPixel(index, 0.0);
	        }
	    }
	    for (int slice=1; slice<p; slice++)
	    {
	        // 1. extract pJ = the (slice-1)th slice of the image J1
	        Matrice pJ = Matrice(m,n);
	        for (int x=0; x<m; x++)
	        {
	            for (int y=0; y<n; y++)
	            {
	                index[0] = x; index[1] = slice-1; index[2] = y;
	                pJ(x,y) = J1->GetPixel(index);
	            }
	        }

	        // 2. extract cP = the (slice)th slice of the image cPixel
	        Matrice cP = Matrice(m,n);
	        for (int x=0; x<m; x++)
	        {
	            for (int y=0; y<n; y++)
	            {
	                index[0] = x; index[1] = slice; index[2] = y;
	                cP(x,y) = cPixel->GetPixel(index);
	            }
	        }

	        // 2'
	        Matrice cPm = Matrice(m,n);
	        if (homoInt)
	        {
	            for (int x=0; x<m; x++)
	            {
	                for (int y=0; y<n; y++)
	                {
	                    index[0] = x; index[1] = slice-1; index[2] = y;
	                    cP(x,y) = cPixel->GetPixel(index);
	                }
	            }
	        }

	        // 3. Create a matrix VI with 5 slices, that are exactly a repetition of cP without borders
	        // multiply all elements of all slices of VI except the middle one by factx
	        Matrice VI[5];
	        for (int i=0; i<5; i++)
	        {
	            // Create VI
	            Matrice cP_in = Matrice(m-1, n-1);
	            for (int x=0; x<m-2; x++)
	            {
	                for (int y=0; y<n-2; y++)
	                {
	                    cP_in(x,y) = cP(x+1,y+1);
	                    if (i!=2)
	                        cP_in(x,y) *= factx;
	                }
	            }
	            VI[i] = cP_in;
	        }

	        // 3'.
	        Matrice VIm[5];
	        if (homoInt)
	        {
	            for (int i=0; i<5; i++)
	            {
	                // Create VIm
	                Matrice cPm_in = Matrice(m-1, n-1);
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        cPm_in(x,y) = cPm(x+1,y+1);
	                        if (i!=2)
	                            cPm_in(x,y) *= factx;
	                    }
	                }
	                VIm[i] = cPm_in;
	            }
	        }

	        // 4. create a matrix of 5 slices, containing pJ(vectx-1,vecty),pJ(vectx,vecty-1),pJ(vectx,vecty),pJ(vectx,vecty+1),pJ(vectx+1,vecty) where vectx=2:m-1; and vecty=2:n-1;
	        Matrice Jq[5];
	        int s = 0;
	        Matrice pJ_temp = Matrice(m-1, n-1);
	        for (int x=0; x<m-2; x++)
	        {
	            for (int y=0; y<n-2; y++)
	            {
	                pJ_temp(x,y) = pJ(x+1,y+1);
	            }
	        }
	        Jq[2] = pJ_temp;
	        for (int k=-1; k<=1; k+=2)
	        {
	            for (int l=-1; l<=1; l+=2)
	            {
	                Matrice pJ_temp = Matrice(m-1, n-1);
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        pJ_temp(x,y) = pJ(x+k+1,y+l+1);
	                    }
	                }
	                Jq[s] = pJ_temp;
	                s++;
	                if (s==2) s++; // we deal with middle slice before
	            }
	        }

	        // 4'. An alternative is to minimize the difference in intensity between slices.
	        if (homoInt)
	        {
	            Matrice VI_temp[5];
	            // compute the difference between VI and VIm
	            for (int i=0; i<5; i++)
	                VI_temp[i] = VI[i] - VIm[i];

	            // compute the minimum value for each element of the matrices
	            for (int i=0; i<5; i++)
	            {
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        if (VI_temp[i](x,y) > 0)
	                            VI[i](x,y) = abs(VI_temp[i](x,y));///VIm[i](x,y);
	                        else
	                            VI[i](x,y) = abs(VI_temp[i](x,y));///VI[i](x,y);
	                    }
	                }
	            }
	        }

	        // 5. sum Jq and Vi voxel by voxel to produce JV
	        Matrice JV[5];
	        for (int i=0; i<5; i++)
	            JV[i] = VI[i] + Jq[i];

	        // 6. replace each pixel of the (slice)th slice of J1 with the minimum value of the corresponding column in JV
	        for (int x=0; x<m-2; x++)
	        {
	            for (int y=0; y<n-2; y++)
	            {
	                double min_value = 1000000;
	                for (int i=0; i<5; i++)
	                {
	                    if (JV[i](x,y) < min_value)
	                        min_value = JV[i](x,y);
	                }
	                index[0] = x+1; index[1] = slice; index[2] = y+1;
	                J1->SetPixel(index, min_value);
	            }
	        }
	    }

	    // iterate on slice from slice n-1 to slice 1. Basically, we avoid first and last slices.
	    // IMPORTANT: first slice of J1 and last slice of J2 must be set to 0...
	    for (int x=0; x<m; x++)
	    {
	        for (int y=0; y<n; y++)
	        {
	            index[0] = x; index[1] = p-1; index[2] = y;
	            J2->SetPixel(index, 0.0);
	        }
	    }
	    for (int slice=p-2; slice>=0; slice--)
	    {
	        // 1. extract pJ = the (slice-1)th slice of the image J1
	        Matrice pJ = Matrice(m,n);
	        for (int x=0; x<m; x++)
	        {
	            for (int y=0; y<n; y++)
	            {
	                index[0] = x; index[1] = slice+1; index[2] = y;
	                pJ(x,y) = J2->GetPixel(index);
	            }
	        }

	        // 2. extract cP = the (slice)th slice of the image cPixel
	        Matrice cP = Matrice(m,n);
	        for (int x=0; x<m; x++)
	        {
	            for (int y=0; y<n; y++)
	            {
	                index[0] = x; index[1] = slice; index[2] = y;
	                cP(x,y) = cPixel->GetPixel(index);
	            }
	        }

	        // 2'
	        Matrice cPm = Matrice(m,n);
	        if (homoInt)
	        {
	            for (int x=0; x<m; x++)
	            {
	                for (int y=0; y<n; y++)
	                {
	                    index[0] = x; index[1] = slice+1; index[2] = y;
	                    cPm(x,y) = cPixel->GetPixel(index);
	                }
	            }
	        }

	        // 3. Create a matrix VI with 5 slices, that are exactly a repetition of cP without borders
	        // multiply all elements of all slices of VI except the middle one by factx
	        Matrice VI[5];
	        for (int i=0; i<5; i++)
	        {
	            // Create VI
	            Matrice cP_in = Matrice(m-1, n-1);
	            for (int x=0; x<m-2; x++)
	            {
	                for (int y=0; y<n-2; y++)
	                {
	                    cP_in(x,y) = cP(x+1,y+1);
	                    if (i!=2)
	                        cP_in(x,y) *= factx;
	                }
	            }
	            VI[i] = cP_in;
	        }

	        // 3'.
	        Matrice VIm[5];
	        if (homoInt)
	        {
	            for (int i=0; i<5; i++)
	            {
	                // Create VI
	                Matrice cPm_in = Matrice(m-1, n-1);
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        cPm_in(x,y) = cPm(x+1,y+1);
	                        if (i!=2)
	                            cPm_in(x,y) *= factx;
	                    }
	                }
	                VIm[i] = cPm_in;
	            }
	        }

	        // 4. create a matrix of 5 slices, containing pJ(vectx-1,vecty),pJ(vectx,vecty-1),pJ(vectx,vecty),pJ(vectx,vecty+1),pJ(vectx+1,vecty) where vectx=2:m-1; and vecty=2:n-1;
	        Matrice Jq[5];
	        int s = 0;
	        Matrice pJ_temp = Matrice(m-1, n-1);
	        for (int x=0; x<m-2; x++)
	        {
	            for (int y=0; y<n-2; y++)
	            {
	                pJ_temp(x,y) = pJ(x+1,y+1);
	            }
	        }
	        Jq[2] = pJ_temp;
	        for (int k=-1; k<=1; k+=2)
	        {
	            for (int l=-1; l<=1; l+=2)
	            {
	                Matrice pJ_temp = Matrice(m-1, n-1);
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        pJ_temp(x,y) = pJ(x+k+1,y+l+1);
	                    }
	                }
	                Jq[s] = pJ_temp;
	                s++;
	                if (s==2) s++; // we deal with middle slice before
	            }
	        }

	        // 4'. An alternative is to minimize the difference in intensity between slices.
	        if (homoInt)
	        {
	            Matrice VI_temp[5];
	            // compute the difference between VI and VIm
	            for (int i=0; i<5; i++)
	                VI_temp[i] = VI[i] - VIm[i];

	            // compute the minimum value for each element of the matrices
	            for (int i=0; i<5; i++)
	            {
	                for (int x=0; x<m-2; x++)
	                {
	                    for (int y=0; y<n-2; y++)
	                    {
	                        if (VI_temp[i](x,y) > 0)
	                            VI[i](x,y) = abs(VI_temp[i](x,y));///VIm[i](x,y);
	                        else
	                            VI[i](x,y) = abs(VI_temp[i](x,y));///VI[i](x,y);
	                    }
	                }
	            }
	        }

	        // 5. sum Jq and Vi voxel by voxel to produce JV
	        Matrice JV[5];
	        for (int i=0; i<5; i++)
	            JV[i] = VI[i] + Jq[i];

	        // 6. replace each pixel of the (slice)th slice of J1 with the minimum value of the corresponding column in JV
	        for (int x=0; x<m-2; x++)
	        {
	            for (int y=0; y<n-2; y++)
	            {
	                double min_value = 10000000;
	                for (int i=0; i<5; i++)
	                {
	                    if (JV[i](x,y) < min_value)
	                        min_value = JV[i](x,y);
	                }
	                index[0] = x+1; index[1] = slice; index[2] = y+1;
	                J2->SetPixel(index, min_value);
	            }
	        }
	    }

	    // add J1 and J2 to produce "S" which is actually J1 here.
	    ImageIterator3D vItS( J1, J1->GetBufferedRegion() );
	    ImageIterator3D vItJ2b( J2, J2->GetBufferedRegion() );
	    vItS.GoToBegin();
	    vItJ2b.GoToBegin();
	    while ( !vItS.IsAtEnd() )
	    {
	        vItS.Set(vItS.Get()+vItJ2b.Get());
	        ++vItS;
	        ++vItJ2b;
	    }

	    // Find the minimal value of S for each slice and create a binary image with all the coordinates
	    // TO DO: the minimal path shouldn't be a pixelar path. It should be a continuous spline that is minimum.
	    double val_temp;
	    vector<CVector3> list_index;
	    for (int slice=1; slice<p-1; slice++)
	    {
	        double min_value_S = 10000000;
	        ImageType::IndexType index_min;
	        for (int x=1; x<m-1; x++)
	        {
	            for (int y=1; y<n-1; y++)
	            {
	                index[0] = x; index[1] = slice; index[2] = y;
	                val_temp = J1->GetPixel(index);
	                if (val_temp < min_value_S)
	                {
	                    min_value_S = val_temp;
	                    index_min = index;
	                }
	            }
	        }
	        list_index.push_back(CVector3(index_min[0], index_min[1], index_min[2]));
	    }

	    //BSplineApproximation centerline_approximator = BSplineApproximation(&list_index);
	    //list_index = centerline_approximator.EvaluateBSplinePoints(list_index.size());

	    /*// create image with high values J1
	    ImageType::Pointer result_bin = J2;
	    ImageIterator3D vItresult( result_bin, result_bin->GetBufferedRegion() );
	    vItresult.GoToBegin();
	    while ( !vItresult.IsAtEnd() )
	    {
	        vItresult.Set(0.0);
	        ++vItresult;
	    }
	    for (int i=0; i<list_index.size(); i++)
	    {
	        index[0] = list_index[i][0]; index[1] = list_index[i][1]; index[2] = list_index[i][2];
	        result_bin->SetPixel(index,1.0);
	    }

	    typedef itk::ImageFileWriter< ImageType > WriterTypeM;
	    WriterTypeM::Pointer writerMin = WriterTypeM::New();
	    itk::NiftiImageIO::Pointer ioV = itk::NiftiImageIO::New();
	    writerMin->SetImageIO(ioV);
	    writerMin->SetInput( J1 ); // result_bin
	    writerMin->SetFileName("minimalPath.nii.gz");
	    try {
	        writerMin->Update();
	    }
	    catch( itk::ExceptionObject & e )
	    {
	        cout << "Exception thrown ! " << endl;
	        cout << "An error ocurred during Writing Min" << endl;
	        cout << "Location    = " << e.GetLocation()    << endl;
	        cout << "Description = " << e.GetDescription() << endl;
	    }*/

	    centerline = list_index;
	    return J1; // return image with minimal path
	}
void NrrdTensorImageReader
::GenerateData()
{
    if ( m_FileName == "")
    {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename is empty!");
    }
    else
    {
        try
        {
            const std::string& locale = "C";
            const std::string& currLocale = setlocale( LC_ALL, NULL );

            if ( locale.compare(currLocale)!=0 )
            {
                try
                {
                    setlocale(LC_ALL, locale.c_str());
                }
                catch(...)
                {
                    MITK_INFO << "Could not set locale " << locale;
                }
            }

            try
            {
                MITK_INFO << "Trying to load dti as nifti ...";
                std::string fname3 = "temp_dti.nii";
                itksys::SystemTools::CopyAFile(m_FileName.c_str(), fname3.c_str());

                typedef itk::Image<float,4> ImageType;
                itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
                typedef itk::ImageFileReader<ImageType> FileReaderType;
                FileReaderType::Pointer reader = FileReaderType::New();
                reader->SetImageIO(io);
                reader->SetFileName(fname3);
                reader->Update();
                itksys::SystemTools::RemoveFile(fname3.c_str());

                ImageType::Pointer img = reader->GetOutput();
                itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

                itk::ImageRegion< 3 > region;
                region.SetSize(0,size[0]);
                region.SetSize(1,size[1]);
                region.SetSize(2,size[2]);
                itk::Vector<double,3> spacing;
                spacing[0] = img->GetSpacing()[0];
                spacing[1] = img->GetSpacing()[1];
                spacing[2] = img->GetSpacing()[2];
                itk::Point<double,3> origin;
                origin[0] = img->GetOrigin()[0];
                origin[1] = img->GetOrigin()[1];
                origin[2] = img->GetOrigin()[2];
                itk::Matrix<double,3,3> direction;
                direction[0][0] = img->GetDirection()[0][0];
                direction[1][0] = img->GetDirection()[1][0];
                direction[2][0] = img->GetDirection()[2][0];
                direction[0][1] = img->GetDirection()[0][1];
                direction[1][1] = img->GetDirection()[1][1];
                direction[2][1] = img->GetDirection()[2][1];
                direction[0][2] = img->GetDirection()[0][2];
                direction[1][2] = img->GetDirection()[1][2];
                direction[2][2] = img->GetDirection()[2][2];

                typedef itk::Image<itk::DiffusionTensor3D<float>,3> VecImgType;
                typedef VecImgType::PixelType FixPixType;
                VecImgType::Pointer vecImg = VecImgType::New();
                vecImg->SetSpacing( spacing );
                vecImg->SetOrigin( origin );
                vecImg->SetDirection( direction );
                vecImg->SetRegions( region );
                vecImg->Allocate();

                itk::ImageRegionIterator<VecImgType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
                ot = ot.Begin();

                while (!ot.IsAtEnd())
                {
                    itk::DiffusionTensor3D<float> tensor;
                    ImageType::IndexType idx;
                    idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

                    if (size[3]==6)
                    {
                        for (int te=0; te<size[3]; te++)
                        {
                            idx[3] = te;
                            tensor.SetElement(te, img->GetPixel(idx));
                        }
                    }
                    else if (size[3]==9)
                    {
                        idx[3] = 0;
                        tensor.SetElement(0, img->GetPixel(idx));
                        idx[3] = 1;
                        tensor.SetElement(1, img->GetPixel(idx));
                        idx[3] = 2;
                        tensor.SetElement(2, img->GetPixel(idx));
                        idx[3] = 4;
                        tensor.SetElement(3, img->GetPixel(idx));
                        idx[3] = 5;
                        tensor.SetElement(4, img->GetPixel(idx));
                        idx[3] = 8;
                        tensor.SetElement(5, img->GetPixel(idx));
                    }
                    else
                        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!");

                    FixPixType fixVec(tensor);
                    ot.Set(fixVec);
                    ++ot;
                }
                this->GetOutput()->InitializeByItk(vecImg.GetPointer());
                this->GetOutput()->SetVolume(vecImg->GetBufferPointer());
            }
            catch(...)
            {
                MITK_INFO << "Trying to load dti as nrrd ...";

                typedef itk::VectorImage<float,3> ImageType;
                itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
                typedef itk::ImageFileReader<ImageType> FileReaderType;
                FileReaderType::Pointer reader = FileReaderType::New();
                reader->SetImageIO(io);
                reader->SetFileName(this->m_FileName);
                reader->Update();
                ImageType::Pointer img = reader->GetOutput();

                typedef itk::Image<itk::DiffusionTensor3D<float>,3> VecImgType;
                VecImgType::Pointer vecImg = VecImgType::New();
                vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
                vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
                vecImg->SetDirection( img->GetDirection() );  // Set the image direction
                vecImg->SetRegions( img->GetLargestPossibleRegion());
                vecImg->Allocate();

                itk::ImageRegionIterator<VecImgType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
                ot = ot.Begin();

                itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );
                it = it.Begin();

                typedef ImageType::PixelType  VarPixType;
                typedef VecImgType::PixelType FixPixType;
                int numComponents = img->GetNumberOfComponentsPerPixel();

                itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
                std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
                std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
                std::string metaString;

                bool readFrame = false;
                double xx, xy, xz, yx, yy, yz, zx, zy, zz;
                MeasurementFrameType measFrame;
                measFrame.SetIdentity();
                MeasurementFrameType measFrameTransp;
                measFrameTransp.SetIdentity();

                for (; itKey != imgMetaKeys.end(); itKey ++)
                {
                    itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
                    if (itKey->find("measurement frame") != std::string::npos)
                    {
                        sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz);

                        if (xx>10e-10 || xy>10e-10 || xz>10e-10 ||
                                yx>10e-10 || yy>10e-10 || yz>10e-10 ||
                                zx>10e-10 || zy>10e-10 || zz>10e-10 )
                        {
                            readFrame = true;

                            measFrame(0,0) = xx;
                            measFrame(0,1) = xy;
                            measFrame(0,2) = xz;
                            measFrame(1,0) = yx;
                            measFrame(1,1) = yy;
                            measFrame(1,2) = yz;
                            measFrame(2,0) = zx;
                            measFrame(2,1) = zy;
                            measFrame(2,2) = zz;

                            measFrameTransp = measFrame.GetTranspose();
                        }
                    }
                }

                if (numComponents==6)
                {
                    while (!it.IsAtEnd())
                    {
                        // T'=RTR'
                        VarPixType vec = it.Get();
                        FixPixType fixVec(vec.GetDataPointer());

                        if(readFrame)
                        {
                            itk::DiffusionTensor3D<float> tensor;
                            tensor.SetElement(0, vec.GetElement(0));
                            tensor.SetElement(1, vec.GetElement(1));
                            tensor.SetElement(2, vec.GetElement(2));
                            tensor.SetElement(3, vec.GetElement(3));
                            tensor.SetElement(4, vec.GetElement(4));
                            tensor.SetElement(5, vec.GetElement(5));

                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
                            fixVec = tensor;
                        }

                        ot.Set(fixVec);
                        ++ot;
                        ++it;
                    }
                }
                else if(numComponents==9)
                {
                    while (!it.IsAtEnd())
                    {
                        VarPixType vec = it.Get();
                        itk::DiffusionTensor3D<float> tensor;
                        tensor.SetElement(0, vec.GetElement(0));
                        tensor.SetElement(1, vec.GetElement(1));
                        tensor.SetElement(2, vec.GetElement(2));
                        tensor.SetElement(3, vec.GetElement(4));
                        tensor.SetElement(4, vec.GetElement(5));
                        tensor.SetElement(5, vec.GetElement(8));

                        if(readFrame)
                        {
                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
                        }

                        FixPixType fixVec(tensor);
                        ot.Set(fixVec);
                        ++ot;
                        ++it;
                    }
                }
                else if (numComponents==1)
                {
                    typedef itk::Image<float,4> ImageType;
                    itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
                    typedef itk::ImageFileReader<ImageType> FileReaderType;
                    FileReaderType::Pointer reader = FileReaderType::New();
                    reader->SetImageIO(io);
                    reader->SetFileName(this->m_FileName);
                    reader->Update();
                    ImageType::Pointer img = reader->GetOutput();

                    itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

                    MITK_INFO << size;

                    while (!ot.IsAtEnd())
                    {
                        itk::DiffusionTensor3D<float> tensor;
                        ImageType::IndexType idx;
                        idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

                        if (size[3]==6)
                        {
                            for (int te=0; te<size[3]; te++)
                            {
                                idx[3] = te;
                                tensor.SetElement(te, img->GetPixel(idx));
                            }

                            //                        idx[3] = 0;
                            //                        tensor.SetElement(0, img->GetPixel(idx));
                            //                        idx[3] = 1;
                            //                        tensor.SetElement(1, img->GetPixel(idx));
                            //                        idx[3] = 3;
                            //                        tensor.SetElement(2, img->GetPixel(idx));
                            //                        idx[3] = 2;
                            //                        tensor.SetElement(3, img->GetPixel(idx));
                            //                        idx[3] = 4;
                            //                        tensor.SetElement(4, img->GetPixel(idx));
                            //                        idx[3] = 5;
                            //                        tensor.SetElement(5, img->GetPixel(idx));
                        }
                        else if (size[3]==9)
                        {
                            idx[3] = 0;
                            tensor.SetElement(0, img->GetPixel(idx));
                            idx[3] = 1;
                            tensor.SetElement(1, img->GetPixel(idx));
                            idx[3] = 2;
                            tensor.SetElement(2, img->GetPixel(idx));
                            idx[3] = 4;
                            tensor.SetElement(3, img->GetPixel(idx));
                            idx[3] = 5;
                            tensor.SetElement(4, img->GetPixel(idx));
                            idx[3] = 8;
                            tensor.SetElement(5, img->GetPixel(idx));
                        }
                        else
                            throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!");

                        if(readFrame)
                        {
                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                            tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
                        }
                        FixPixType fixVec(tensor);
                        ot.Set(fixVec);
                        ++ot;
                    }
                }
                else
                {
                    throw itk::ImageFileReaderException(__FILE__, __LINE__, "Image has wrong number of pixel components!");
                }

                this->GetOutput()->InitializeByItk(vecImg.GetPointer());
                this->GetOutput()->SetVolume(vecImg->GetBufferPointer());

            }

            try
            {
                setlocale(LC_ALL, currLocale.c_str());
            }
            catch(...)
            {
                MITK_INFO << "Could not reset locale " << currLocale;
            }

        }
        catch(std::exception& e)
        {
            throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
        }
        catch(...)
        {
            throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested DTI file!");
        }
    }
}
int main(int argc, char* *argv)
{


	     GetPot   cl(argc, argv);
	     if( cl.size() == 1 || cl.search(2, "--help", "-h") )
	      {
	          std::cout << "Not enough arguments" << std::endl;
	          return -1;
	      }

	const string image_n = cl.follow("NoFile", 1, "-i");
	const string maskImage_n  =  cl.follow("NoFile", 1, "-m");

	typedef itk::Image<float, 3> ImageType;
	typedef itk::ImageFileReader<ImageType> ReaderType;

	ReaderType::Pointer reader = ReaderType::New();

	reader->SetFileName(maskImage_n.c_str());
	reader-> Update();
	ImageType::Pointer maskimage = reader->GetOutput();

 	typedef itk::ImageRegionIterator<ImageType> ImageIterator;
	ImageIterator it(maskimage, maskimage->GetLargestPossibleRegion());

	typedef itk::DiffusionTensor3D<float> DiffusionTensorType;
	typedef itk::Image<DiffusionTensorType, 3> TensorImageType;
	typedef itk::ImageFileReader<TensorImageType> TensorImageReaderType;
	TensorImageReaderType::Pointer tensorReader = TensorImageReaderType::New();

	tensorReader->SetFileName(image_n.c_str());
	tensorReader->Update();
	TensorImageType::Pointer tensorImage = tensorReader->GetOutput();

	typedef itk::ImageRegionIterator<TensorImageType> TensorIterator;
	TensorIterator itT(tensorImage, tensorImage->GetLargestPossibleRegion());
	
	typedef DiffusionTensorType::EigenValuesArrayType EigenArrayType;

	ImageType::Pointer Eig1 = ImageType::New();
	ImageType::Pointer Eig2 = ImageType::New();
	ImageType::Pointer Eig3 = ImageType::New();

	CopyImage cpImage;
	cpImage.CopyScalarImage(maskimage, Eig1);
	cpImage.CopyScalarImage(maskimage, Eig2);
	cpImage.CopyScalarImage(maskimage, Eig3);

	TensorImageType::Pointer tensorProb = TensorImageType::New();
	cpImage.CopyTensorImage(tensorImage, tensorProb);

	DiffusionTensorType D_Identity;
	
	vnl_matrix<float> ZeroD_mat; ZeroD_mat.set_size(3,3);
 	ZeroD_mat.set_identity();

	TensorUtilities utils;
	D_Identity = utils.ConvertMat2DT(ZeroD_mat);

	//tensorProb->FillBuffer(D_Identity);
	
	for (it.GoToBegin(), itT.GoToBegin(); !it.IsAtEnd(), !itT.IsAtEnd(); ++it, ++itT)
	{
		if (it.Get() != 0)
		{
			EigenArrayType eig;
			DiffusionTensorType D = itT.Get();
			D.ComputeEigenValues(eig);
			
			if ( (eig[0] < 0) || (eig[1] < 0 ) || (eig[2] < 0) || eig[0] > 5 || (eig[1] > 5) || (eig[2] > 5))
			{
				tensorProb->SetPixel(itT.GetIndex(), D);	
				std::cout << eig << std::endl;	
			}			
			
		
		}
	}	

	typedef itk::ImageFileWriter<TensorImageType> TensorImageWriter;
	TensorImageWriter::Pointer tensorWriter = TensorImageWriter::New();
	tensorWriter->SetFileName("TensorImage_Prob.nii.gz");
	tensorWriter->SetInput(tensorProb);
	tensorWriter->Update();
	
	return 0;
}
        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);
            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, options );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            notice()<<"Reading DICOM file "<<fileName<<std::endl;

            typedef unsigned short PixelType;
            const unsigned int Dimension = 3;
            typedef itk::Image< PixelType, Dimension > ImageType;


            typedef itk::ImageFileReader< ImageType > ReaderType;
            ReaderType::Pointer reader = ReaderType::New();
            reader->SetFileName( fileName.c_str() );

            typedef itk::GDCMImageIO           ImageIOType;
            ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
            reader->SetImageIO( gdcmImageIO );

            try
            {
                reader->Update();
            }
            catch (itk::ExceptionObject & e)
            {
                std::cerr << "exception in file reader " << std::endl;
                std::cerr << e.GetDescription() << std::endl;
                std::cerr << e.GetLocation() << std::endl;
                return ReadResult::ERROR_IN_READING_FILE;
            }
            
            ImageType::Pointer inputImage = reader->GetOutput();
            
            ImageType::RegionType region = inputImage->GetBufferedRegion();
            ImageType::SizeType size = region.GetSize();
            ImageType::IndexType start = region.GetIndex();
            
            //inputImage->GetSpacing();
            //inputImage->GetOrigin();
            
            unsigned int width = size[0];
            unsigned int height = size[1];
            unsigned int depth = size[2];
            
            osg::RefMatrix* matrix = new osg::RefMatrix;
            
            notice()<<"width = "<<width<<" height = "<<height<<" depth = "<<depth<<std::endl;
            for(unsigned int i=0; i<Dimension; ++i)
            {
                (*matrix)(i,i) = inputImage->GetSpacing()[i];
                (*matrix)(3,i) = inputImage->GetOrigin()[i];
            }
            
            osg::Image* image = new osg::Image;
            image->allocateImage(width, height, depth, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1);

            unsigned char* data = image->data();            
            typedef itk::ImageRegionConstIterator< ImageType > IteratorType;
            IteratorType it(inputImage, region);
            
            it.GoToBegin();
            while (!it.IsAtEnd())
            {
                *data = it.Get();
                ++data;
                ++it;
            }
            
            image->setUserData(matrix);
            
            matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r())));

            return image;
        }
int main(int argc, char *argv[])
{

  //check that the user specified the right number of command line arguments
  if(argc < 3)
    {
    cerr << argv[0] << " <input file> <output file>" << endl;
    cerr << argv[0] << " <raw input file> <sizeX> <sizeY> <sizeZ> <output file>"
         << endl;
    return EXIT_FAILURE;
    }

  //check if the input image is .raw
  bool rawInput = false;
  string inputFileName = argv[1];
  const char *outputFileName;
  //double space[3]={1,1,1};
  if(inputFileName.rfind(".raw") != string::npos)
    {
    //if so, the user is also required to pass in image dimensions
    if(argc < 6)
      {
      cerr << "Usage: <raw input file> <sizeX> <sizeY> <sizeZ> <output file>" << endl;
      return EXIT_FAILURE;
      }
    rawInput = true;
    sizeX = atoi(argv[2]);
    sizeY = atoi(argv[3]);
    sizeZ = atoi(argv[4]);
    outputFileName = argv[5];
    }
  else
    {
    outputFileName = argv[2];
    }

  FILE *infile = 0;
  FILE *outfile;
  int i,j,k;
  int ii, jj, kk;
  DATATYPEOUT *volout;
  long idx;

 
  int sizeExpand = 0;
  DATATYPEOUT blockMax;
  int timesDilate;
  int border;
  unsigned short *GraphcutResults;

  cout << "Volume Processing..." << endl;
  //make sure we can write to the output file
  if((outfile=fopen(outputFileName, "wb")) == NULL)
    {
    cerr << "Output file open error!" << endl;
    return EXIT_FAILURE;
    }

 
    typedef float     PixelType;
    const   unsigned int      Dimension = 3;
    typedef itk::Image< PixelType, Dimension >    ImageType;
    ImageType::Pointer inputImage;

   if(rawInput)
    {
    if((infile=fopen(inputFileName.c_str(), "rb"))==NULL)
      {
      cout << "Input file open error!" << endl;
      return EXIT_FAILURE;
      }

    volin = (DATATYPEIN*)malloc(sizeX*sizeY*(sizeZ+sizeExpand*2)*sizeof(DATATYPEIN));

    if (fread(volin, sizeof(DATATYPEIN), sizeX*sizeY*sizeZ, infile) < (unsigned int)(sizeX*sizeY*sizeZ))
      {
      cerr << "File size is not the same as volume size" << endl;
      return EXIT_FAILURE;
      }
    
	inputImage = ImageType::New();

	ImageType::PointType origin;
    origin[0] = 0.; 
    origin[1] = 0.;    
    origin[2] = 0.;    
	inputImage->SetOrigin( origin );

	ImageType::IndexType start;
    start[0] =   0;  
    start[1] =   0;  
	start[2] =   0;  

	ImageType::SizeType  size;
    size[0]  = sizeX;  
    size[1]  = sizeY;  
	size[2]  = sizeZ;  

    ImageType::RegionType region;
    region.SetSize( size );
    region.SetIndex( start );
    
    inputImage->SetRegions( region );
    inputImage->Allocate();
    inputImage->FillBuffer(0);
	inputImage->Update();
	
	typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;
	IteratorType iterator1(inputImage,inputImage->GetRequestedRegion());
	int lng = sizeX*sizeY*sizeZ;
	
	for(int i=0; i<lng; i++)
	{
	 iterator1.Set((float)volin[i]);
	 ++iterator1;	
	}
  } // end if(rawInput)

   else
    {
  
    typedef itk::ImageFileReader< ImageType >  ReaderType;
    ReaderType::Pointer reader = ReaderType::New();

    inputImage = reader->GetOutput();
    reader->SetFileName( inputFileName.c_str()  );
    try 
      { 
      reader->Update(); 
      } 
    catch( itk::ExceptionObject & err ) 
      { 
      cerr << "ExceptionObject caught!" << endl; 
      cerr << err << endl; 
      return EXIT_FAILURE;
      } 
	} // end of itk image read 

 
	 // ---------------Linear Mapping --------------------//
    typedef itk::RescaleIntensityImageFilter<
               ImageType, ImageType>  RescaleFilterType;
    RescaleFilterType::Pointer    rescaleFilter    = RescaleFilterType::New();
    rescaleFilter->SetInput(inputImage);
	rescaleFilter->SetOutputMinimum(  0 );
    rescaleFilter->SetOutputMaximum( 255 );
	
	try 
      { 
       rescaleFilter->Update();
      } 
    catch( itk::ExceptionObject & err ) 
      { 
      cerr << "ExceptionObject caught!" << endl; 
      cerr << err << endl; 
      return EXIT_FAILURE;
      }

	inputImage = rescaleFilter->GetOutput();
	cout << "The Linear Mapping is done\n";

    # if Curvature_Anistropic_Diffusion 
	{
     cout << "The Curvature Diffusion is doing\n"; 
	 typedef itk::CurvatureAnisotropicDiffusionImageFilter<
               ImageType, ImageType >  MCD_FilterType;

     MCD_FilterType::Pointer MCDFilter = MCD_FilterType::New();
    
     //Initialnization,  using the paper's optimal parameters
     const unsigned int numberOfIterations = 5;
     const double       timeStep = 0.0425;
     const double       conductance = 3;
     MCDFilter->SetNumberOfIterations(numberOfIterations);
     MCDFilter->SetTimeStep( timeStep );
     MCDFilter->SetConductanceParameter( conductance );
     MCDFilter->SetInput(inputImage);
	 try 
      { 
       MCDFilter->Update();
      } 
     catch( itk::ExceptionObject & err ) 
      { 
      cerr << "ExceptionObject caught!" << endl; 
      cerr << err << endl; 
      return EXIT_FAILURE;
      } 
     inputImage=MCDFilter->GetOutput(); 
     cout << "The Curvature Diffusion is done\n";
	}
	#endif

    ImageType::RegionType region = inputImage->GetBufferedRegion();
    ImageType::SizeType  size = region.GetSize();
    cout << "input image size: " << size << endl;
    sizeX = size[0];
    sizeY = size[1];
    sizeZ = size[2];
    itk::ImageRegionIterator< ImageType >
      itr( inputImage, inputImage->GetBufferedRegion() );
    itr.GoToBegin();
    idx = 0;
    volin = (DATATYPEIN*)malloc(sizeX*sizeY*(sizeZ+sizeExpand*2)*sizeof(DATATYPEIN));
    while( ! itr.IsAtEnd() )
      {
      volin[idx] = itr.Get();
      ++itr;
      ++idx;
      }
  //allocate memory for the output image
  volout = (DATATYPEOUT*)malloc(sizeX*sizeY*(sizeZ+sizeExpand*2)*sizeof(DATATYPEOUT));
  
  // one pre-processing  scheme 
  
  GraphcutResults = (unsigned short*)malloc(sizeX*sizeY*(sizeZ+sizeExpand*2)*sizeof(unsigned short));
  Neuron_Binarization_3D(volin,GraphcutResults,sizeX,sizeY,sizeZ,0,1);
  
  for (k=0; k<(sizeZ+sizeExpand*2); k++)
      for (j=0; j<sizeY; j++)
        for (i=0; i<sizeX; i++) {
          volout[k *sizeX*sizeY + j *sizeX + i] = 0; 
        }  //initial to zeros
   
  
  std::cout << "Do you think we need the distance transform to make the centerline of image become bright with higher intensity?";
  
  char tmpAnswer = 'n';
  //tmpAnswer = getchar();
  if (tmpAnswer =='Y' || tmpAnswer =='y')
  {
  unsigned char *GraphcutResultsTmp;
  GraphcutResultsTmp = (unsigned char*)malloc(sizeX*sizeY*(sizeZ+sizeExpand*2)*sizeof(unsigned char));
  for (k=0; k<(sizeZ+sizeExpand*2); k++)
      for (j=0; j<sizeY; j++)
        for (i=0; i<sizeX; i++) 
		{
          GraphcutResultsTmp[k *sizeX*sizeY + j *sizeX + i] = (unsigned char) GraphcutResults[k *sizeX*sizeY + j *sizeX + i]; 
        }  //initial to zeros

  distTransform(GraphcutResultsTmp,sizeX,sizeY,sizeZ);
  
  for (k=0; k<sizeZ; k++)
    {
    // threshold first
     for (j=0; j<sizeY; j++)
       {
       for (i=0; i<sizeX; i++)
        {
        idx = k *sizeX*sizeY + j *sizeX + i;
        volin[idx] = GraphcutResultsTmp [idx];
        } // end for 
      } // end for 
    } // end for 
  
  free(GraphcutResultsTmp);
  GraphcutResultsTmp=NULL;
  } // end if 

  else {
 
   for (k=0; k<sizeZ; k++)
    {
    // threshold first
     for (j=0; j<sizeY; j++)
       {
       for (i=0; i<sizeX; i++)
        {
        idx = k *sizeX*sizeY + j *sizeX + i;
		
        if (GraphcutResults [idx] == 0) 
          {
          volin[idx] = 0;
          }
        }
      }
    }   

 } // end else

 free(GraphcutResults);
 GraphcutResults=NULL;

  // the secpnd Pre-Processing method, corresponding to the old version MDL 
  /*
  double threshold; 
  // by xiao liang, using 3 sigma theory to estimate threshold;
  double meanValue =0.0, VarianceValue =  0.0;

  // threshold first
  for (k=0; k<sizeZ; k++)
    {
    for (j=0; j<sizeY; j++) 
      {
      for (i=0; i<sizeX; i++)
        {
        idx = k *sizeX*sizeY + j *sizeX + i;
        meanValue += volin[idx];
        }
      }
    }

  meanValue = meanValue/(double)(sizeX*sizeY*sizeZ);
  // threshold first
  for (k=0; k<sizeZ; k++)
    {
    for (j=0; j<sizeY; j++) 
      {
      for (i=0; i<sizeX; i++)
        {
        idx = k *sizeX*sizeY + j *sizeX + i;
        VarianceValue += (volin[idx]-meanValue)*(volin[idx]-meanValue);
        }
      }
    }

  VarianceValue =  VarianceValue/(double)(sizeX*sizeY*sizeZ);
  VarianceValue = sqrt(VarianceValue);

  double m_threshold=OtsuThreshold (sizeX,sizeY,sizeZ);
  if (m_threshold > 7 || m_threshold < 0)
    {
    threshold =(meanValue-VarianceValue/30); 
    }
  else
    {
    threshold = m_threshold;
    }

  //threshold =7;
  cout << "OTSU optimal threshold " << threshold << endl;

     for (k=0; k<(sizeZ+sizeExpand*2); k++)
      for (j=0; j<sizeY; j++)
        for (i=0; i<sizeX; i++) {

          volout[k *sizeX*sizeY + j *sizeX + i] = 0; 
        }  //initial to zeros

  for (k=0; k<sizeZ; k++)
    {
    // threshold first
    for (j=0; j<sizeY; j++)
      {
      for (i=0; i<sizeX; i++)
        {
        idx = k *sizeX*sizeY + j *sizeX + i;
        if (volin[idx] < threshold) 
          {
          volin[idx] = 0;
          }
        }
      }
    }   
  */
  // Method 2: Dilation of the object
  timesDilate = 1;
  border = 3;
  while (timesDilate >0 )
    {
    for (k=border; k<sizeZ-border; k++)
      {
      for (j=border; j<sizeY-border; j++)
        {
        for (i=border; i<sizeX-border; i++)
          {
          blockMax = volin[k *sizeX*sizeY + j *sizeX + i];
          for (kk=-1; kk<=1; kk++)
            {
            for (jj=-1; jj<=1; jj++)
              {
              for (ii=-1; ii<=1; ii++)
                {
                if(volin[(k+kk)*sizeX*sizeY + (j+jj)*sizeX + (i+ii)] > blockMax) 
                  {
                  blockMax = volin[(k+kk)*sizeX*sizeY + (j+jj)*sizeX + (i+ii)];
                  }
                }
              }
            }
          // Keep the peak of the original intensity
          if (blockMax == volin[k *sizeX*sizeY + j *sizeX + i] && blockMax != 0)
            {
            blockMax = blockMax + 1;
            //if (blockMax > 255)   blockMax = 255;
            }
          volout[k *sizeX*sizeY + j *sizeX + i] = blockMax;
          }
        }
      }

    // copy volout back to volin for the next dilation
    for (k=0; k<sizeZ; k++) 
      {
      for (j=0; j<sizeY; j++) 
        {
        for (i=0; i<sizeX; i++)
          {
          volin[k *sizeX*sizeY + j *sizeX + i] = volout[k *sizeX*sizeY + j *sizeX + i];
          }
        }
      }
    timesDilate--;
    }

  //-----  Image write 
   /*
    typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;
	IteratorType iterator1(inputImage,inputImage->GetRequestedRegion());
	int lng = sizeX*sizeY*sizeZ;
	
	for(int i=0; i<lng; i++)
	{
	 iterator1.Set((float)volin[i]);
	 ++iterator1;	
	}
   */
  //write the output image and free memory
  fwrite(volout, sizeX*sizeY*sizeZ, sizeof(DATATYPEOUT), outfile);
  FILE *mhdfile;
  
  if((mhdfile=fopen("volume_Processed.mhd","w"))==NULL)
    {
    cerr << "output file open error!" << endl;
    return -1;
    }
  fprintf (mhdfile,"ObjectType = Image\n");
  fprintf (mhdfile,"NDims = 3\n");
  fprintf (mhdfile,"BinaryData = True\n");
  fprintf (mhdfile,"BinaryDataByteOrderMSB = False\n");
  fprintf (mhdfile,"CompressedData = False\n");
  fprintf (mhdfile,"TransformMatrix = 1 0 0 0 1 0 0 0 1\n");
  fprintf (mhdfile,"Offset = 0 0 0\n");
  fprintf (mhdfile,"CenterOfRotation = 0 0 0\n");
  fprintf (mhdfile,"AnatomicalOrientation = RAI\n");
  fprintf (mhdfile,"ElementSpacing = 1 1 1\n");
  fprintf (mhdfile,"DimSize = %d %d %d\n",sizeX,sizeY,sizeZ);
  fprintf (mhdfile,"ElementType = MET_UCHAR\n");
  fprintf (mhdfile,"ElementDataFile = volume_Processed.raw\n");
  fclose(mhdfile);

  if (rawInput)
	  fclose(infile);
  fclose(outfile);

  free(volin);  // by xiao
  free(volout); // by xiao
  volin=NULL;
  volout=NULL;

  //cout << "Done" << endl;
  return 0;
}
Example #24
0
void MakeDices(const char * montagefileName, const char * seedfileName, int diceWidth, 
			   double alfa, double beta, int timethreshold, double curvatureScaling, double rmsThres, int holeSize, int minObjSize)
{
	typedef SomaExtractor::ProbImageType ImageType;
	typedef SomaExtractor::OutputImageType OutputImageType;
	typedef itk::RegionOfInterestImageFilter< ImageType, ImageType> RegionOfInterestFilter;
	SomaExtractor *Somas = new SomaExtractor();

	std::cout<< "ReadMontage..."<<std::endl;
	ImageType::Pointer image = Somas->SetInputImage(montagefileName);
	int SZ = image->GetLargestPossibleRegion().GetSize()[2];

	std::vector< itk::Index<3> > seedVector;
	Somas->ReadSeedpoints( seedfileName, seedVector, 0);
	std::cout<< "Seed points size:"<< seedVector.size()<<std::endl;	

	#pragma omp parallel for
	for(int i = 0; i < seedVector.size(); i++)
	{
		SomaExtractor *somaExtractor = new SomaExtractor();
		ImageType::IndexType start;
		start[0] = seedVector[i][0] - diceWidth / 2;
		start[1] = seedVector[i][1] - diceWidth / 2;
		start[2] = 0;
		ImageType::SizeType size;
		size[0] = diceWidth;
		size[1] = diceWidth;
		size[2] = SZ;

		ImageType::RegionType desiredRegion;
		desiredRegion.SetSize(size);
		desiredRegion.SetIndex(start);

		RegionOfInterestFilter::Pointer regionFilter = RegionOfInterestFilter::New();
		regionFilter->SetInput(image);
		regionFilter->SetRegionOfInterest(desiredRegion);
		regionFilter->Update();
		ImageType::Pointer diceImage = regionFilter->GetOutput();
		std::ostringstream oss1;
		oss1<< "Dice_"<< i<<".tif";
		std::string str1 = oss1.str();
		somaExtractor->writeImage(str1.c_str(), diceImage);
		
		std::vector< itk::Index<3> > seedsForDice;
		itk::Index<3> seedIndex = seedVector[i];
		seedIndex[0] = diceWidth / 2;
		seedIndex[1] = diceWidth / 2;
		seedsForDice.push_back(seedIndex);

		float Origion[3] = {0,0,0};
		diceImage->SetOrigin(Origion);

		//SomaExtractor::SegmentedImageType::Pointer segImage= somaExtractor->SegmentSoma(diceImage, seedsForDice, alfa, 
		//					beta, timethreshold, curvatureScaling, rmsThres, holeSize, minObjSize);
		//double threshold = 0;
//		//ImageType::Pointer segImage = Somas->EnhanceContrast(diceImage, seedIndex[2], alfa, beta, threshold);
//
//#pragma omp critical
//		std::cout<< "segment "<< i<<"\t"<<seedsForDice.size()<<std::endl;
//		std::ostringstream oss;
//		oss<< "Dice_Segment_"<< i<<".tif";
//		std::string str = oss.str();
//		somaExtractor->writeImage(str.c_str(), segImage);
		delete somaExtractor;
	}
	delete Somas;
}
int main(int argc, char ** argv)
{
	std::string folderName = argv[1];
	std::string filter = argv[2];

	typedef utils::Directory Directory;
	Directory::FilenamesType filenames = Directory::GetFiles(folderName, ".nrrd");

	Directory::FilenamesType goodFilenames;
	filterFilenames(filenames, filter, goodFilenames);

	// load the images
	std::vector<ImageType::Pointer> imageList;
	for(unsigned int i = 0; i < goodFilenames.size(); i++)
	{
		std::cout << goodFilenames[i] << std::endl;

		typedef itk::ImageFileReader<ImageType> ReaderType;

		ReaderType::Pointer reader = ReaderType::New();
		reader->SetFileName(goodFilenames[i]);
		reader->SetImageIO(itk::NrrdImageIO::New());
		reader->Update();

		imageList.push_back(reader->GetOutput());

	}

	std::sort(imageList.begin(), imageList.end(), imageSort);

	ImageType::Pointer outputImage = ImageType::New();
	ImageType::RegionType outputRegion;
	ImageType::SizeType outputSize = imageList.front()->GetLargestPossibleRegion().GetSize();
	outputSize[2] = imageList.size(); 
	ImageType::IndexType outputIndex;
	outputIndex.Fill(0);
	outputRegion.SetSize(outputSize);
	outputRegion.SetIndex(outputIndex);

	// compute the spacing 
	double meanSpacing = 0.0;
	for(unsigned int i = 1; i < imageList.size(); i++)
	{
		ImageType::Pointer im1 = imageList[i-1];
		ImageType::Pointer im2 = imageList[i];

		meanSpacing += (im1->GetOrigin()-im2->GetOrigin()).GetNorm();
	}

	meanSpacing /= (double) (imageList.size()-1);
	ImageType::SpacingType spacing = imageList.front()->GetSpacing();
	spacing[2] = meanSpacing;

	outputImage->SetRegions(outputRegion);
	outputImage->SetSpacing(spacing);
	outputImage->SetOrigin(imageList.front()->GetOrigin());
	outputImage->SetDirection(imageList.front()->GetDirection());
	outputImage->Allocate();

	itk::ImageRegionIterator<ImageType> outIt(outputImage, outputImage->GetLargestPossibleRegion());
	outIt.GoToBegin();

	while(!outIt.IsAtEnd())
	{
		ImageType::IndexType index = outIt.GetIndex();
		ImageType::IndexType testIndex = index;
		testIndex[2] = 0;

		outIt.Set(imageList[index[2]]->GetPixel(testIndex));


		++outIt;
	}

	std::string stackFilename = folderName + "/stack.nrrd";


	typedef itk::ImageFileWriter<ImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetInput(outputImage);
	writer->SetFileName(stackFilename);
	writer->SetImageIO(itk::NrrdImageIO::New());
	writer->Update();

	return 0;

}
// Run with: Data/trashcan.mha Data/trashcan_mask.mha 15 filled.mha
int main(int argc, char *argv[])
{
  // Verify arguments
  if(argc != 6)
    {
    std::cerr << "Required arguments: image.mha imageMask.mha patchHalfWidth neighborhoodRadius output.mha" << std::endl;
    std::cerr << "Input arguments: ";
    for(int i = 1; i < argc; ++i)
      {
      std::cerr << argv[i] << " ";
      }
    return EXIT_FAILURE;
    }

  // Parse arguments
  std::string imageFileName = argv[1];
  std::string maskFileName = argv[2];

  std::stringstream ssPatchRadius;
  ssPatchRadius << argv[3];
  unsigned int patchHalfWidth = 0;
  ssPatchRadius >> patchHalfWidth;

  // The percent of the image size to use as the neighborhood (0 - 1)
  std::stringstream ssNeighborhoodPercent;
  ssNeighborhoodPercent << argv[4];
  float neighborhoodPercent = 0;
  ssNeighborhoodPercent >> neighborhoodPercent;

  std::string outputFileName = argv[5];

  // Output arguments
  std::cout << "Reading image: " << imageFileName << std::endl;
  std::cout << "Reading mask: " << maskFileName << std::endl;
  std::cout << "Patch half width: " << patchHalfWidth << std::endl;
  std::cout << "Neighborhood percent: " << neighborhoodPercent << std::endl;
  std::cout << "Output: " << outputFileName << std::endl;

  typedef itk::Image<itk::CovariantVector<int, 3>, 2> ImageType;

  typedef  itk::ImageFileReader<ImageType> ImageReaderType;
  ImageReaderType::Pointer imageReader = ImageReaderType::New();
  imageReader->SetFileName(imageFileName);
  imageReader->Update();

  ImageType::Pointer image = ImageType::New();
  ITKHelpers::DeepCopy(imageReader->GetOutput(), image.GetPointer());

  Mask::Pointer mask = Mask::New();
  mask->Read(maskFileName);

  std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl;
  std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl;

  typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType;

  // Create the graph
  typedef boost::grid_graph<2> VertexListGraphType;
  boost::array<std::size_t, 2> graphSideLengths = { { imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0],
                                                      imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] } };
//  VertexListGraphType graph(graphSideLengths);
  std::shared_ptr<VertexListGraphType> graph(new VertexListGraphType(graphSideLengths));
  typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType;


  //ImagePatchDescriptorMapType smallImagePatchDescriptorMap(num_vertices(graph), indexMap);

  // Create the patch inpainter. The inpainter needs to know the status of each pixel to determine if they should be inpainted.

  typedef PatchInpainter<ImageType> ImageInpainterType;
  std::shared_ptr<ImageInpainterType> imagePatchInpainter(new
      ImageInpainterType(patchHalfWidth, image, mask));

  // Create the priority function
   typedef PriorityRandom PriorityType;
   std::shared_ptr<PriorityType> priorityFunction(new PriorityType);
//  typedef PriorityCriminisi<ImageType> PriorityType;
//  std::shared_ptr<PriorityType> priorityFunction(new PriorityType(image, mask, patchHalfWidth));

  typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType;
  std::shared_ptr<BoundaryNodeQueueType> boundaryNodeQueue(new BoundaryNodeQueueType(*graph));

  // Create the descriptor map. This is where the data for each pixel is stored.
  typedef boost::vector_property_map<ImagePatchPixelDescriptorType, BoundaryNodeQueueType::IndexMapType> ImagePatchDescriptorMapType;
//  ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap);
  std::shared_ptr<ImagePatchDescriptorMapType> imagePatchDescriptorMap(new
      ImagePatchDescriptorMapType(num_vertices(*graph), *(boundaryNodeQueue->GetIndexMap())));

  // Create the descriptor visitor
  typedef ImagePatchDescriptorVisitor<VertexListGraphType, ImageType, ImagePatchDescriptorMapType>
          ImagePatchDescriptorVisitorType;
//  ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(image, mask, imagePatchDescriptorMap, patchHalfWidth);
  std::shared_ptr<ImagePatchDescriptorVisitorType> imagePatchDescriptorVisitor(new
      ImagePatchDescriptorVisitorType(image.GetPointer(), mask,
                                      imagePatchDescriptorMap, patchHalfWidth));
/*   ImagePatchDescriptorVisitor(TImage* const in_image, Mask* const in_mask,
  std::shared_ptr<TDescriptorMap> in_descriptorMap,
  const unsigned int in_half_width) : */
  typedef ImagePatchDifference<ImagePatchPixelDescriptorType, SumAbsolutePixelDifference<ImageType::PixelType> >
            ImagePatchDifferenceType;

//  typedef CompositeDescriptorVisitor<VertexListGraphType> CompositeDescriptorVisitorType;
//  CompositeDescriptorVisitorType compositeDescriptorVisitor;
//  compositeDescriptorVisitor.AddVisitor(imagePatchDescriptorVisitor);

  // Create the descriptor visitor


//  typedef CompositeAcceptanceVisitor<VertexListGraphType> CompositeAcceptanceVisitorType;
//  CompositeAcceptanceVisitorType compositeAcceptanceVisitor;

  typedef DefaultAcceptanceVisitor<VertexListGraphType> AcceptanceVisitorType;
  std::shared_ptr<AcceptanceVisitorType> acceptanceVisitor(new AcceptanceVisitorType);

//  typedef AlwaysAccept<VertexListGraphType> AcceptanceVisitorType;
//  AcceptanceVisitorType acceptanceVisitor;



  // If the hole is less than 15% of the patch, always accept the initial best match
//  HoleSizeAcceptanceVisitor<VertexListGraphType> holeSizeAcceptanceVisitor(mask, patchHalfWidth, .15);
//  compositeAcceptanceVisitor.AddOverrideVisitor(&holeSizeAcceptanceVisitor);

//  AllQuadrantHistogramCompareAcceptanceVisitor<VertexListGraphType, ImageType>
//               allQuadrantHistogramCompareAcceptanceVisitor(image, mask, patchHalfWidth, 8.0f); // Crazy low
//  compositeAcceptanceVisitor.AddRequiredPassVisitor(&allQuadrantHistogramCompareAcceptanceVisitor);

//  template <typename TGraph, typename TBoundaryNodeQueue,
//            typename TDescriptorVisitor, typename TAcceptanceVisitor, typename TPriority>

  typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType,
                            ImagePatchDescriptorVisitorType, AcceptanceVisitorType, PriorityType>
                            InpaintingVisitorType;
  std::shared_ptr<InpaintingVisitorType> inpaintingVisitor(new InpaintingVisitorType(mask, boundaryNodeQueue,
                                                                                     imagePatchDescriptorVisitor, acceptanceVisitor,
                                                                                     priorityFunction, patchHalfWidth, "InpaintingVisitor"));

//  typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType,
//                            ImagePatchDescriptorVisitorType, AcceptanceVisitorType, PriorityType>
//                            InpaintingVisitorType;
//  std::shared_ptr<InpaintingVisitorType> inpaintingVisitor(new InpaintingVisitorType(mask, boundaryNodeQueue,
//                                          imagePatchDescriptorVisitor, acceptanceVisitor,
//                                          priorityFunction, patchHalfWidth, "InpaintingVisitor"));

//  typedef DebugVisitor<VertexListGraphType, ImageType, BoundaryStatusMapType, BoundaryNodeQueueType> DebugVisitorType;
//  DebugVisitorType debugVisitor(image, mask, patchHalfWidth, boundaryStatusMap, boundaryNodeQueue);

  LoggerVisitor<VertexListGraphType> loggerVisitor("log.txt");

  InitializePriority(mask, boundaryNodeQueue.get(), priorityFunction.get());
  // Initialize the boundary node queue from the user provided mask image.
  InitializeFromMaskImage<InpaintingVisitorType, VertexDescriptorType>(mask, inpaintingVisitor.get());

  // For debugging we use LinearSearchBestProperty instead of DefaultSearchBest because it can output the difference value.
  typedef LinearSearchBestProperty<ImagePatchDescriptorMapType,
                                   ImagePatchDifferenceType > BestSearchType;
  std::shared_ptr<BestSearchType> linearSearchBest(new BestSearchType(*imagePatchDescriptorMap));

  typedef NeighborhoodSearch<VertexDescriptorType, ImagePatchDescriptorMapType> NeighborhoodSearchType;
  NeighborhoodSearchType neighborhoodSearch(image->GetLargestPossibleRegion(), image->GetLargestPossibleRegion().GetSize()[0] * neighborhoodPercent, *imagePatchDescriptorMap);
  
  InpaintingAlgorithmWithLocalSearch<VertexListGraphType, InpaintingVisitorType,
                      BoundaryNodeQueueType, NeighborhoodSearchType,
                      ImageInpainterType, BestSearchType>(graph, inpaintingVisitor, boundaryNodeQueue,
                      linearSearchBest, imagePatchInpainter, neighborhoodSearch);

  // If the output filename is a png file, then use the RGBImage writer so that it is first
  // casted to unsigned char. Otherwise, write the file directly.
  if(Helpers::GetFileExtension(outputFileName) == "png")
  {
    ITKHelpers::WriteRGBImage(image.GetPointer(), outputFileName);
  }
  else
  {
    ITKHelpers::WriteImage(image.GetPointer(), outputFileName);
  }

  return EXIT_SUCCESS;
}
Example #27
0
  std::vector<itk::SmartPointer<BaseData> > NrrdTensorImageReader::Read()
  {
    std::vector<itk::SmartPointer<mitk::BaseData> > result;
    std::string location = GetInputLocation();

    if ( location == "")
    {
      throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename is empty!");
    }
    else
    {
      try
      {
        mitk::LocaleSwitch localeSwitch("C");

        try
        {
          std::string fname3 = mitk::IOUtil::GetTempPath()+"/temp_dti.nii.gz";

          int c = 0;
          while( itksys::SystemTools::FileExists(fname3) )
          {
            fname3 = mitk::IOUtil::GetTempPath()+"/temp_dti_" + boost::lexical_cast<std::string>(c) + ".nii.gz";
            ++c;
          }

          itksys::SystemTools::CopyAFile(location.c_str(), fname3.c_str());

          typedef itk::VectorImage<float,3> ImageType;
          itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
          typedef itk::ImageFileReader<ImageType> FileReaderType;
          FileReaderType::Pointer reader = FileReaderType::New();
          reader->SetImageIO(io);
          reader->SetFileName(fname3);
          reader->Update();
          ImageType::Pointer img = reader->GetOutput();

          TensorImage::ItkTensorImageType::Pointer vecImg = TensorImage::ItkTensorImageType::New();
          vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
          vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
          vecImg->SetDirection( img->GetDirection() );  // Set the image direction
          vecImg->SetRegions( img->GetLargestPossibleRegion());
          vecImg->Allocate();

          itk::ImageRegionIterator<TensorImage::ItkTensorImageType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
          ot.GoToBegin();

          itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );
          it.GoToBegin();

          typedef ImageType::PixelType  VarPixType;
          typedef TensorImage::PixelType FixPixType;
          int numComponents = img->GetNumberOfComponentsPerPixel();

          if (numComponents==6)
          {
            MITK_INFO << "Trying to load dti as 6-comp nifti ...";
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              FixPixType fixVec(vec.GetDataPointer());

              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(3));
              tensor.SetElement(4, vec.GetElement(4));
              tensor.SetElement(5, vec.GetElement(5));

              fixVec = tensor;

              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if(numComponents==9)
          {
            MITK_INFO << "Trying to load dti as 9-comp nifti ...";
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(4));
              tensor.SetElement(4, vec.GetElement(5));
              tensor.SetElement(5, vec.GetElement(8));

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if (numComponents==1)
          {
            MITK_INFO << "Trying to load dti as 4D nifti ...";
            typedef itk::Image<float,4> ImageType;
            typedef itk::ImageFileReader<ImageType> FileReaderType;
            FileReaderType::Pointer reader = FileReaderType::New();
            reader->SetImageIO(io);
            reader->SetFileName(fname3);
            reader->Update();
            ImageType::Pointer img = reader->GetOutput();

            itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

            while (!ot.IsAtEnd())
            {
              TensorImage::PixelType tensor;
              ImageType::IndexType idx;
              idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

              if (size[3]==6)
              {
                for (unsigned int te=0; te<size[3]; te++)
                {
                  idx[3] = te;
                  tensor.SetElement(te, img->GetPixel(idx));
                }
              }
              else if (size[3]==9)
              {
                idx[3] = 0;
                tensor.SetElement(0, img->GetPixel(idx));
                idx[3] = 1;
                tensor.SetElement(1, img->GetPixel(idx));
                idx[3] = 2;
                tensor.SetElement(2, img->GetPixel(idx));
                idx[3] = 4;
                tensor.SetElement(3, img->GetPixel(idx));
                idx[3] = 5;
                tensor.SetElement(4, img->GetPixel(idx));
                idx[3] = 8;
                tensor.SetElement(5, img->GetPixel(idx));
              }
              else
                throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of components for DTI file. Should be 6 or 9!");

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
            }
          }
          OutputType::Pointer resultImage = OutputType::New();
          resultImage->InitializeByItk( vecImg.GetPointer() );
          resultImage->SetVolume( vecImg->GetBufferPointer() );
          result.push_back( resultImage.GetPointer() );
        }
        catch(...)
        {
          MITK_INFO << "Trying to load dti as nrrd ...";

          typedef itk::VectorImage<float,3> ImageType;
          itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
          typedef itk::ImageFileReader<ImageType> FileReaderType;
          FileReaderType::Pointer reader = FileReaderType::New();
          reader->SetImageIO(io);
          reader->SetFileName(location);
          reader->Update();
          ImageType::Pointer img = reader->GetOutput();

          TensorImage::ItkTensorImageType::Pointer vecImg = TensorImage::ItkTensorImageType::New();
          vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
          vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
          vecImg->SetDirection( img->GetDirection() );  // Set the image direction
          vecImg->SetRegions( img->GetLargestPossibleRegion());
          vecImg->Allocate();

          itk::ImageRegionIterator<TensorImage::ItkTensorImageType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
          ot.GoToBegin();

          itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );
          it.GoToBegin();

          typedef ImageType::PixelType  VarPixType;
          typedef TensorImage::PixelType FixPixType;
          int numComponents = img->GetNumberOfComponentsPerPixel();

          itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
          std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
          std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
          std::string metaString;

          bool readFrame = false;
          double xx, xy, xz, yx, yy, yz, zx, zy, zz;
          MeasurementFrameType measFrame;
          measFrame.SetIdentity();
          MeasurementFrameType measFrameTransp;
          measFrameTransp.SetIdentity();

          for (; itKey != imgMetaKeys.end(); itKey ++)
          {
            itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
            if (itKey->find("measurement frame") != std::string::npos)
            {
              sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz);

              if (xx>10e-10 || xy>10e-10 || xz>10e-10 ||
                yx>10e-10 || yy>10e-10 || yz>10e-10 ||
                zx>10e-10 || zy>10e-10 || zz>10e-10 )
              {
                readFrame = true;

                measFrame(0,0) = xx;
                measFrame(0,1) = xy;
                measFrame(0,2) = xz;
                measFrame(1,0) = yx;
                measFrame(1,1) = yy;
                measFrame(1,2) = yz;
                measFrame(2,0) = zx;
                measFrame(2,1) = zy;
                measFrame(2,2) = zz;

                measFrameTransp = measFrame.GetTranspose();
              }
            }
          }

          if (numComponents==6)
          {
            while (!it.IsAtEnd())
            {
              // T'=RTR'
              VarPixType vec = it.Get();
              FixPixType fixVec(vec.GetDataPointer());

              if(readFrame)
              {
                TensorImage::PixelType tensor;
                tensor.SetElement(0, vec.GetElement(0));
                tensor.SetElement(1, vec.GetElement(1));
                tensor.SetElement(2, vec.GetElement(2));
                tensor.SetElement(3, vec.GetElement(3));
                tensor.SetElement(4, vec.GetElement(4));
                tensor.SetElement(5, vec.GetElement(5));

                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
                fixVec = tensor;
              }

              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if(numComponents==9)
          {
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(4));
              tensor.SetElement(4, vec.GetElement(5));
              tensor.SetElement(5, vec.GetElement(8));

              if(readFrame)
              {
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
              }

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if (numComponents==1)
          {
            typedef itk::Image<float,4> ImageType;
            itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
            typedef itk::ImageFileReader<ImageType> FileReaderType;
            FileReaderType::Pointer reader = FileReaderType::New();
            reader->SetImageIO(io);
            reader->SetFileName(location);
            reader->Update();
            ImageType::Pointer img = reader->GetOutput();

            itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

            while (!ot.IsAtEnd())
            {
              TensorImage::PixelType tensor;
              ImageType::IndexType idx;
              idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

              if (size[3]==6)
              {
                for (unsigned int te=0; te<size[3]; te++)
                {
                  idx[3] = te;
                  tensor.SetElement(te, img->GetPixel(idx));
                }
              }
              else if (size[3]==9)
              {
                idx[3] = 0;
                tensor.SetElement(0, img->GetPixel(idx));
                idx[3] = 1;
                tensor.SetElement(1, img->GetPixel(idx));
                idx[3] = 2;
                tensor.SetElement(2, img->GetPixel(idx));
                idx[3] = 4;
                tensor.SetElement(3, img->GetPixel(idx));
                idx[3] = 5;
                tensor.SetElement(4, img->GetPixel(idx));
                idx[3] = 8;
                tensor.SetElement(5, img->GetPixel(idx));
              }
              else
                throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!");

              if(readFrame)
              {
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
              }
              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
            }
          }
          else
          {
            throw itk::ImageFileReaderException(__FILE__, __LINE__, "Image has wrong number of pixel components!");
          }

          OutputType::Pointer resultImage = OutputType::New();
          resultImage->InitializeByItk( vecImg.GetPointer() );
          resultImage->SetVolume( vecImg->GetBufferPointer() );
          result.push_back( resultImage.GetPointer() );
        }

      }
      catch(std::exception& e)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
      }
      catch(...)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested DTI file!");
      }
    }

    return result;
  }
void TestComputeMaskedImage1DHistogram()
{
//  // Single channel
//  {
//  typedef itk::Image<unsigned char, 2> ImageType;
//  ImageType::Pointer image = ImageType::New();
//  ImageType::IndexType corner = {{0,0}};

//  ImageType::SizeType size = {{100,100}};

//  ImageType::RegionType region(corner, size);

//  image->SetRegions(region);
//  image->Allocate();

//  itk::ImageRegionIterator<ImageType> imageIterator(image,region);

//  while(!imageIterator.IsAtEnd())
//    {
//    if(imageIterator.GetIndex()[0] < 70)
//      {
//      imageIterator.Set(255);
//      }
//    else
//      {
//      imageIterator.Set(0);
//      }

//    ++imageIterator;
//    }

//  ImageType::PixelType rangeMin = 0;
//  ImageType::PixelType rangeMax = 255;

//  unsigned int numberOfBins = 10;
//  typedef int BinValueType;
//  typedef Histogram<BinValueType>::HistogramType HistogramType;

//  HistogramType histogram = Histogram<BinValueType>::ComputeImageHistogram1D(image.GetPointer(),
//                                                         image->GetLargestPossibleRegion(),
//                                                         numberOfBins, rangeMin, rangeMax);

//  Histogram<BinValueType>::OutputHistogram(histogram);
//  std::cout << std::endl;
//  }

   // Multi channel VectorImage
   {
   typedef itk::VectorImage<unsigned char, 2> ImageType;
   ImageType::Pointer image = ImageType::New();
   ImageType::IndexType corner = {{0,0}};

   ImageType::SizeType size = {{100,100}};

   ImageType::RegionType region(corner, size);

   image->SetRegions(region);
   image->SetNumberOfComponentsPerPixel(3);
   image->Allocate();

   Mask::Pointer mask = Mask::New();
   mask->SetRegions(region);
   mask->Allocate();

   itk::ImageRegionIterator<ImageType> imageIterator(image,region);

   while(!imageIterator.IsAtEnd())
   {
     ImageType::PixelType pixel(image->GetNumberOfComponentsPerPixel());
     if(imageIterator.GetIndex()[0] < 70)
     {
       for(unsigned int i = 0; i < pixel.GetSize(); ++i)
       {
         pixel[i] = 255;
       }
     }
     else
     {
       for(unsigned int i = 0; i < pixel.GetSize(); ++i)
       {
         pixel[i] = 0;
       }
     }
     imageIterator.Set(pixel);
     ++imageIterator;
   }

//   TypeTraits<ImageType::PixelType>::ComponentType rangeMin = 0;
//   TypeTraits<ImageType::PixelType>::ComponentType rangeMax = 255;

   ImageType::PixelType rangeMins;
   rangeMins.SetSize(image->GetNumberOfComponentsPerPixel());
   rangeMins.Fill(0);

   ImageType::PixelType rangeMaxs;
   rangeMaxs.SetSize(image->GetNumberOfComponentsPerPixel());
   rangeMaxs.Fill(255);

   unsigned int numberOfBinsPerComponent = 10;
   typedef int BinValueType;

   itk::ImageRegion<2> imageRegion = image->GetLargestPossibleRegion();
   itk::ImageRegion<2> maskRegion = image->GetLargestPossibleRegion();

   typedef MaskedHistogramGenerator<BinValueType> HistogramGeneratorType;
   typedef HistogramGeneratorType::HistogramType HistogramType;

   bool allowOutside = false;

   HistogramType histogram =
       HistogramGeneratorType::ComputeMaskedImage1DHistogram(image.GetPointer(), imageRegion,
                                                      mask.GetPointer(), maskRegion,
                                                      numberOfBinsPerComponent, rangeMins, rangeMaxs,
                                                      allowOutside, HoleMaskPixelTypeEnum::VALID);

   histogram.Print();
   std::cout << std::endl;
   }

//  // Multi channel Image<CovariantVector>
//  {
//  typedef itk::Image<itk::CovariantVector<unsigned char, 3>, 2> ImageType;
//  ImageType::Pointer image = ImageType::New();
//  ImageType::IndexType corner = {{0,0}};

//  ImageType::SizeType size = {{100,100}};

//  ImageType::RegionType region(corner, size);

//  image->SetRegions(region);
//  image->Allocate();

//  itk::ImageRegionIterator<ImageType> imageIterator(image,region);

//  while(!imageIterator.IsAtEnd())
//    {
//    ImageType::PixelType pixel(image->GetNumberOfComponentsPerPixel());
//    if(imageIterator.GetIndex()[0] < 70)
//      {
//      for(unsigned int i = 0; i < pixel.GetNumberOfComponents(); ++i)
//        {
//        pixel[i] = 255;
//        }
//      }
//    else
//      {
//      for(unsigned int i = 0; i < pixel.GetNumberOfComponents(); ++i)
//        {
//        pixel[i] = 0;
//        }
//      }
//    imageIterator.Set(pixel);
//    ++imageIterator;
//    }

//  TypeTraits<ImageType::PixelType>::ComponentType rangeMin = 0;
//  TypeTraits<ImageType::PixelType>::ComponentType rangeMax = 255;

//  unsigned int numberOfBinsPerComponent = 10;
//  typedef int BinValueType;
//  Histogram<BinValueType>::HistogramType histogram = Histogram<BinValueType>::ComputeImageHistogram1D(image.GetPointer(),
//                                                         image->GetLargestPossibleRegion(),
//                                                         numberOfBinsPerComponent, rangeMin, rangeMax);

//  Histogram<BinValueType>::OutputHistogram(histogram);
//  std::cout << std::endl;
//  }
}
  void NrrdQBallImageReader
    ::GenerateData()
  {
    if ( m_FileName == "")
    {
      throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename of the vessel tree to be read is empty!");
    }
    else
    {
      try
      {
        const std::string& locale = "C";
        const std::string& currLocale = setlocale( LC_ALL, NULL );

        if ( locale.compare(currLocale)!=0 )
        {
          try
          {
            setlocale(LC_ALL, locale.c_str());
          }
          catch(...)
          {
            MITK_INFO << "Could not set locale " << locale;
          }
        }

        typedef itk::VectorImage<float,3> ImageType;
        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        typedef itk::ImageFileReader<ImageType> FileReaderType;
        FileReaderType::Pointer reader = FileReaderType::New();
        reader->SetImageIO(io);
        reader->SetFileName(this->m_FileName);
        reader->Update();
        ImageType::Pointer img = reader->GetOutput();

        typedef itk::Image<itk::Vector<float,QBALL_ODFSIZE>,3> VecImgType;
        VecImgType::Pointer vecImg = VecImgType::New();
        vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
        vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
        vecImg->SetDirection( img->GetDirection() );  // Set the image direction
        vecImg->SetLargestPossibleRegion( img->GetLargestPossibleRegion());
        vecImg->SetBufferedRegion( img->GetLargestPossibleRegion() );
        vecImg->Allocate();

        itk::ImageRegionIterator<VecImgType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
        ot = ot.Begin();

        itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );

        typedef ImageType::PixelType  VarPixType;
        typedef VecImgType::PixelType FixPixType;

        for (it = it.Begin(); !it.IsAtEnd(); ++it)
        {
          VarPixType vec = it.Get();
          FixPixType fixVec(vec.GetDataPointer());
          ot.Set(fixVec);
          ++ot;
        }

        this->GetOutput()->InitializeByItk(vecImg.GetPointer());
        this->GetOutput()->SetVolume(vecImg->GetBufferPointer());

        try
        {
          setlocale(LC_ALL, currLocale.c_str());
        }
        catch(...)
        {
          MITK_INFO << "Could not reset locale " << currLocale;
        }
      }
      catch(std::exception& e)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
      }
      catch(...)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!");
      }
    }
  }
int main(int, char ** argv)
{
	OptionsData options;
	readXMLValues(argv[2], options);
	
	exit(1);


	// parse the dicom directory
	gdcm::Directory dir;
	dir.Load(argv[1], true);
	gdcm::Directory::FilenamesType filenames = dir.GetFilenames();

	
	gdcm::Tag seriesDescription = gdcm::Tag(0x0008,0x103e);
	gdcm::Tag seriesNumber = gdcm::Tag(0x0020,0x0011);
	gdcm::Tag instanceNumber = gdcm::Tag(0x0020,0x0013);
	gdcm::Tag sliceThickness = gdcm::Tag(0x0018,0x0050);
	gdcm::Tag triggerTime = gdcm::Tag(0x0018,0x1060);
	gdcm::Tag numberOfImages = gdcm::Tag(0x0018,0x1090);
	gdcm::Tag slicePosition = gdcm::Tag(0x0019,0x1015);
	gdcm::Tag imagePosition = gdcm::Tag(0x0020,0x0032);
	gdcm::Tag imageOrientation = gdcm::Tag(0x0020,0x0037);
	gdcm::Tag sliceLocation = gdcm::Tag(0x0020,0x1041);
	gdcm::Tag rows = gdcm::Tag(0x0028,0x0010);
	gdcm::Tag cols = gdcm::Tag(0x0028,0x0011);
	gdcm::Tag pixelSpacing = gdcm::Tag(0x0028,0x0030);

	gdcm::Scanner scanner;
	scanner.AddTag(seriesDescription);
	scanner.AddTag(seriesNumber);
	scanner.AddTag(instanceNumber);
	scanner.AddTag(sliceThickness);
	scanner.AddTag(triggerTime);
	scanner.AddTag(numberOfImages);
	scanner.AddTag(slicePosition);
	scanner.AddTag(imagePosition);
	scanner.AddTag(imageOrientation);
	scanner.AddTag(sliceLocation);
	scanner.AddTag(rows);
	scanner.AddTag(cols);
	scanner.AddTag(pixelSpacing);

	scanner.Scan(filenames);
	gdcm::Scanner::MappingType mapping = scanner.GetMappings();


	// extract all the images that are Short axis and are the first instance
	gdcm::Directory::FilenamesType targetFilenames;
	for(unsigned int i = 0; i < filenames.size(); i++)
	{
		const char * fname = filenames[i].c_str();
		if(mapping.count(fname) == 0) continue;


		// extract the image information
		std::string descriptionStr = mapping[fname][seriesDescription];
		std::string instanceNumberStr = mapping[fname][instanceNumber];
		QString description = QString::fromStdString(descriptionStr);
		unsigned int instanceNumber = QString::fromStdString(instanceNumberStr).toInt();

		// check that the description is a short axis one and is instance 1
		if(instanceNumber == 1 && description.contains("sa", Qt::CaseInsensitive))
		{
			targetFilenames.push_back(filenames[i]);
		}
	}


	// sort the images based on their slice position
	/*
	gdcm::Sorter sorter;
	sorter.SetSortFunction(position_sort);
	sorter.StableSort(targetFilenames);

	gdcm::Directory::FilenamesType sorted = sorter.GetFilenames();
	for(unsigned int i = 0; i < sorted.size(); i++)
	{
		const char * fname = sorted[i].c_str();
		std::string position = mapping[fname][imagePosition];
		std::cout << position << std::endl;
		std::cout << mapping[fname][sliceLocation] << std::endl;
	}
	*/

	std::cout << targetFilenames.size() << std::endl;


	// find the slice with the smallest slice position
	double smallest = 1000000.0;
	int smallestIndex;
	for(unsigned int i = 0; i < targetFilenames.size(); i++)
	{
		const char * fname = targetFilenames[i].c_str();
		std::string slicePosition = mapping[fname][sliceLocation];
		double pos = QString::fromStdString(slicePosition).toDouble();

		std::cout << pos << std::endl;
		if(pos < smallest)
		{	
			smallest = pos;
			smallestIndex = i;
		}
	}

	// load the image
	typedef itk::Image<unsigned short, 3> ImageType;
	typedef itk::ImageFileReader<ImageType> ReaderType;
	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(targetFilenames[smallestIndex]);
	reader->SetImageIO(itk::GDCMImageIO::New());
	reader->Update();

	
	// flip the x and y axis
	typedef itk::PermuteAxesImageFilter<ImageType> FlipperType;
	FlipperType::Pointer flipper = FlipperType::New();
	itk::FixedArray<unsigned int, 3> order;
	order[0] = 1;
	order[1] = 0;
	order[2] = 2;
	flipper->SetOrder(order);
	flipper->SetInput(reader->GetOutput());
	flipper->Update();


	ImageType::Pointer referenceImage = flipper->GetOutput();
	ImageType::DirectionType direction = referenceImage->GetDirection();
	direction.SetIdentity();
	referenceImage->SetDirection(direction);
	
	ImageType::PointType origin = referenceImage->GetOrigin();
	origin.Fill(20.0);
	referenceImage->SetOrigin(origin);

	ImageType::SpacingType spacing;
	spacing.Fill(1.0);

	referenceImage->SetSpacing(spacing);


	
	flipper->GetOutput()->Print(std::cout);

	typedef itk::ImageFileWriter<ImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetInput(referenceImage);
	writer->SetImageIO(itk::NrrdImageIO::New());
	writer->SetFileName("test.nrrd");
	writer->Update();

	std::cout << targetFilenames[smallestIndex] << std::endl;

	return 0;
}