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();
}
int main(int, char ** argv)
{
	// load the input nifti image
	std::string inputFolderName = argv[1];
	std::string outputFilename = argv[2];


	// get the set of images from the input folder
	QStringList nameFilters;
	nameFilters << "phiContour*_t=*_final.nii";

	QDir inputFolder(QString::fromStdString(inputFolderName));
	QStringList inputFiles = inputFolder.entryList(nameFilters);
	unsigned int numTimeSteps = inputFiles.size();
	qSort(inputFiles.begin(), inputFiles.end(), file_sort);

	std::cout << "--> Found " << numTimeSteps << " segmentations" << std::endl;
	std::cout << "--> Loading images and thresholding " << std::endl;


	utils::LabelVolumeList labels;


	for(unsigned int i = 0; i < numTimeSteps; i++)
	{
		std::cout << "\t" << inputFiles[i].toStdString() << std::endl;

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

		std::string filename = inputFolderName + "/" + inputFiles[i].toStdString(); 

		ReaderType::Pointer reader  = ReaderType::New();
		reader->SetFileName(filename);
		reader->SetImageIO(itk::NiftiImageIO::New());
		reader->Update();

		typedef itk::BinaryThresholdImageFilter<InputImageType, utils::LabelVolume> ThresholderType;
		ThresholderType::Pointer thresholder = ThresholderType::New();
		thresholder->SetInput(reader->GetOutput());
		thresholder->SetOutsideValue(0);
		thresholder->SetInsideValue(1);
		thresholder->SetLowerThreshold(0);
		thresholder->SetUpperThreshold(255);
		thresholder->Update();


		labels.push_back(thresholder->GetOutput());
	}


	
	// build the output image 
	typedef itk::Image<unsigned char, 4> OutputType;
	OutputType::Pointer output = OutputType::New();

	typedef itk::JoinSeriesImageFilter<utils::LabelVolume, OutputType> JoinerType;
	JoinerType::Pointer joiner = JoinerType::New();
	joiner->SetSpacing(1.0);
	joiner->SetOrigin(0);

	for(unsigned int i = 0; i < labels.size(); i++)
	{
		joiner->SetInput(i, labels[i]);
	}

	joiner->Update();
	output = joiner->GetOutput();



	// save the output
	typedef itk::ImageFileWriter<OutputType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetInput(output);
	writer->SetFileName(outputFilename);
	writer->Update();

	/*

	utils::LabelVolume::Pointer ref = labels[0];

	OutputType::SpacingType outSpacing;
	OutputType::DirectionType outDirection;
	outDirection.SetIdentity();
	OutputType::PointType outOrigin;

	for(unsigned int i = 0; i < 3; i++)
	{
		outSpacing[i] = ref->GetSpacing()[i];
		outOrigin[i] = ref->GetOrigin()[i];
		

	
	}
	
	
	



	return 0;
	



	

	
   		
	utils::LabelVolumeIO::Write(outputFilename, thresholder->GetOutput());
	*/

	return 0;

}