// ------------------------------------------------------------------------
void LoadImage(const std::string &filename, ImageType::Pointer &image)
{
	typedef itk::Image<unsigned short, 4> InImageType;
	typedef itk::ImageFileReader<InImageType> ReaderType;
	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(filename);
	reader->SetImageIO(itk::NrrdImageIO::New());
	reader->Update();


	typedef itk::ExtractImageFilter<InImageType, ImageType> ExtractorType;
	ExtractorType::Pointer extractor = ExtractorType::New();
	extractor->SetInput(reader->GetOutput());

	InImageType::RegionType exRegion = reader->GetOutput()->GetLargestPossibleRegion();
	InImageType::SizeType exSize = exRegion.GetSize();
	InImageType::IndexType exIndex = exRegion.GetIndex();

	exSize[3] = 0;
	exIndex[3] = 0;
	exRegion.SetSize(exSize);
	exRegion.SetIndex(exIndex);

	extractor->SetExtractionRegion(exRegion);
	extractor->SetDirectionCollapseToSubmatrix();
	extractor->Update();

	image = extractor->GetOutput();



}
// ------------------------------------------------------------------------
void loadImageSeries(SeriesTransform &series,
		const unsigned int &instanceNumbers)
{
	// resize the image vector
	series.images.resize(series.imageFilenames.size());

	typedef itk::GDCMImageIO IOType;
	typedef itk::ImageFileReader<ImageType> ReaderType;

	for(unsigned int i = 0; i < instanceNumbers; i++)
	{
		ReaderType::Pointer reader = ReaderType::New();
		reader->SetImageIO(IOType::New());
		reader->SetFileName(series.imageFilenames[i]);
		
		try 
		{
			reader->Update();
		}
		catch(itk::ExceptionObject &e)
		{	
			std::cout << e << std::endl;
			exit(1);
		}

		series.images[i] = reader->GetOutput();
	}
}
//read CT image
void CTImageTreeItem::retrieveITKImage(QProgressDialog *progress, int progressScale, int progressBase) {
	//define and create file reader
	typedef ReaderProgress::ReaderType ReaderType;
	ReaderType::Pointer imageReader = ReaderType::New();
	ReaderType::FileNamesContainer fc;
	//assign filenames
	fc.assign(m_fnList.begin(), m_fnList.end());
	//set ImageIO and filenames
	itk::GDCMImageIO::Pointer gdcmImageIO = itk::GDCMImageIO::New();
	imageReader->SetImageIO( gdcmImageIO );
	imageReader->SetFileNames(fc);
	//create reader progress
	ReaderProgress::Pointer progressor = ReaderProgress::New();
	if (progress) 
	{
		progressor->setDialog( progress, progressScale, progressBase );
		imageReader->AddObserver(itk::AnyEvent(), progressor);
	}
	//try to read the images
	try {
		imageReader->Update();
	}catch( itk::ExceptionObject & excep ) {
		std::cerr << "Exception caught !" << std::endl;
		std::cerr << excep << std::endl;
	}
	//assign the reader output to an image pointer
	ImageType::Pointer imagePtr =  imageReader->GetOutput();
	setITKImage(imagePtr, 1);
	//emit signal, that data has changed
	m_model->dataChanged(m_model->createIndex(childNumber(),0,parent()),m_model->createIndex(childNumber(),columnCount()-1,parent()));
}
int main(int argc, char** argv) {
	if(argc != 3){
		std::cout << "Usage: Test2DImage inputFilename outputFilename"; 
		return 1;
	}
	typedef signed int InputPixelType;
	const unsigned int Dimension = 2;
	typedef itk::Image<InputPixelType, Dimension> InputImageType;
	typedef itk::RGBPixel<unsigned char> RGBPixelType;
	typedef itk::Image<RGBPixelType, 2> RGBImageType;
	typedef itk::ImageFileReader<InputImageType> ReaderType;
	typedef itk::ImageFileWriter<RGBImageType> WriterType;
	typedef itk::GDCMImageIO ImageIOType;
	typedef itk::GradientAnisotropicDiffusionImageFilter<InputImageType,
	InputImageType> DiffusionFilterType;
	typedef itk::GradientMagnitudeImageFilter<InputImageType, InputImageType>
			GradientMagnitudeFilterType;
	typedef itk::Functor::ScalarToRGBPixelFunctor<int> ColorMapFunctorType;
	typedef itk::UnaryFunctorImageFilter<InputImageType,
	RGBImageType, ColorMapFunctorType> ColorMapFilterType;
	typedef itk::JPEGImageIO JImageIOType;

	ReaderType::Pointer reader = ReaderType::New();
	WriterType::Pointer writer = WriterType::New();
	ImageIOType::Pointer GDCMImageIO = ImageIOType::New();
	JImageIOType::Pointer JPEGImageIO = JImageIOType::New();
	ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();

	reader->SetFileName(argv[1]);
	reader->SetImageIO(GDCMImageIO);

	try {
		reader->Update();
	}
	catch (itk::ExceptionObject & e) {
		std::cerr << "exception in file reader " << std::endl;
		std::cerr << e << std::endl;
		return 1;
	}
	DiffusionFilterType::Pointer diffusion = DiffusionFilterType::New();
	diffusion->SetNumberOfIterations(1);
	diffusion->SetConductanceParameter(4);
	diffusion->SetTimeStep(0.125);
	GradientMagnitudeFilterType::Pointer gradient = GradientMagnitudeFilterType::New();
	diffusion->SetInput(reader->GetOutput());
	gradient->SetInput(diffusion->GetOutput());
	gradient->Update();
	MyWatershedSegmenter<InputImageType> watershed(gradient->GetOutput());
	watershed.buildLowerCompleteImage();
	watershed.buildLabeledImage();
	colormapper->SetInput(watershed.returnFinalImage());
	writer->SetInput(colormapper->GetOutput());
	writer->UseInputMetaDataDictionaryOff();
	writer->SetImageIO(JPEGImageIO);
	writer->SetFileName(argv[2]);
	writer->Update();
}
bool extractPointAndNormalFromMask(string filename, CVector3 &point, CVector3 &normal1, CVector3 &normal2)
{
    ReaderType::Pointer reader = ReaderType::New();
	itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
	reader->SetImageIO(io);
	reader->SetFileName(filename);
    try {
        reader->Update();
    } catch( itk::ExceptionObject & e ) {
        cerr << "Exception caught while reading input image " << endl;
        cerr << e << endl;
        return false;
    }
    ImageType::Pointer image = reader->GetOutput();
    
    vector<CVector3> result;
    ImageType::IndexType ind;
    itk::Point<double,3> pnt;
    ImageIterator it( image, image->GetRequestedRegion() );
    it.GoToBegin();
    while(!it.IsAtEnd())
    {
        if (it.Get()!=0)
        {
            ind = it.GetIndex();
            image->TransformIndexToPhysicalPoint(ind, pnt);
            bool added = false;
            if (result.size() == 0) {
                result.push_back(CVector3(pnt[0],pnt[1],pnt[2]));
                added = true;
            }
            else {
                for (vector<CVector3>::iterator it=result.begin(); it!=result.end(); it++) {
                    if (pnt[2] < (*it)[2]) {
                        result.insert(it, CVector3(pnt[0],pnt[1],pnt[2]));
                        added = true;
                        break;
                    }
                }
            }
            if (!added) result.push_back(CVector3(pnt[0],pnt[1],pnt[2]));
        }
        ++it;
    }
    
    if (result.size() != 3) {
        cerr << "Error: Not enough of too many points in the binary mask. Number of point needed = 3. Detected points = " << result.size() << endl;
        return false;
    }
    point = result[1];
    normal1 = (result[0]-result[1]).Normalize();
    normal2 = (result[2]-result[1]).Normalize();
    
    return true;
}
// ------------------------------------------------------------------------
void DicomParser::writeSeries(const DicomSeries &series, const QString &outputFolder)
{
	// create the series name
	QString name = QString::fromStdString(series.description);
	name.replace(" ","_");
	name += "_" + QString::number(series.images.front().seriesNumber);
	name += ".nrrd";
	
	QDir path(outputFolder);
	QString fullPath = path.absoluteFilePath(name);
	

	std::vector<DicomImage> images = series.images;
	std::sort(images.begin(), images.end());

	// write and build the output images 
	typedef itk::Image<unsigned short, 3> ImageType;
	typedef itk::Image<unsigned short, 4> OutputImageType;
	typedef itk::ImageFileReader<ImageType> ReaderType;
	typedef itk::JoinSeriesImageFilter<ImageType, OutputImageType> JoinerType;

	JoinerType::Pointer joiner = JoinerType::New();
	ImageType::Pointer orig;
	for(unsigned int i = 0; i < images.size(); i++)
	{
		ReaderType::Pointer reader = ReaderType::New();
		reader->SetFileName(images[i].filename);
		std::cout << images[i].filename << std::endl;
		reader->SetImageIO(itk::GDCMImageIO::New());
		reader->Update();

		ImageType::Pointer im = reader->GetOutput();
		if(i == 0) orig = im;


		im->SetOrigin(orig->GetOrigin());
		im->SetDirection(orig->GetDirection());
		im->SetSpacing(orig->GetSpacing());

		joiner->SetInput(i, reader->GetOutput());
	}


	std::cout << joiner->GetOutput()->GetDirection() << std::endl;


	typedef itk::ImageFileWriter<OutputImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetInput(joiner->GetOutput());
	writer->SetFileName(fullPath.toStdString());
	writer->SetImageIO(itk::NrrdImageIO::New());
	writer->Update();

}
Exemple #7
0
FilterImageType::Pointer getImage(const FileNamesContainer &filenames, DictionaryArray &dictArray) {
	typedef itk::ImageSeriesReader< FilterImageType > ReaderType;
	ReaderType::Pointer reader = ReaderType::New();
	ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
	reader->SetImageIO( gdcmImageIO );
	reader->SetFileNames(filenames);
	reader->Update();
	ReaderType::DictionaryArrayRawPointer dict;

	dict = reader->GetMetaDataDictionaryArray();
	for( ReaderType::DictionaryArrayType::const_iterator it = dict->begin(); it != dict->end(); ++it) {
		dictArray.push_back( **it );
	}
	
	return reader->GetOutput();
}
Exemple #8
0
itk::Image<unsigned char, 3>::Pointer boner::Importer::import(std::string path)
{

    itk::Image<unsigned char, 3>::Pointer image;

    typedef itk::ImageSeriesReader<itk::Image<unsigned char, 3>> ReaderType;
    ReaderType::Pointer reader = ReaderType::New();
    itk::GDCMSeriesFileNames::Pointer namegenerator = itk::GDCMSeriesFileNames::New();
    namegenerator->SetInputDirectory(path);

    reader->SetImageIO(itk::GDCMImageIO::New());

    reader->SetFileNames(namegenerator->GetInputFileNames());
    image = reader->GetOutput();
    image->Update();

    return image;
}
// ------------------------------------------------------------------------
void InitialTransformExtractor::Compute()
{
    GetFilenames(m_Filenames);
    BuildMapping(m_Mapping);
    std::string referenceFilename = GetReferenceImageFilename();


    // load the reference file
    typedef itk::ImageFileReader<ImageType> ReaderType;
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(referenceFilename);
    reader->SetImageIO(itk::GDCMImageIO::New());
    reader->Update();
    ImageType::Pointer refImage = reader->GetOutput();


    // 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(refImage);
    flipper->Update();

    //refImage = flipper->GetOutput();

    // transformation is the negative origin of the reference
    ImageType::PointType origin = refImage->GetOrigin();
    m_Translation[0] = -origin[0];
    m_Translation[1] = -origin[1];
    m_Translation[2] = -origin[2];

    m_Rotation = refImage->GetDirection().GetInverse();
    m_Reference = refImage;
}
Exemple #10
0
void
NrrdPlugin::readSlice(int idx[3], int sz[3],
		       int nbytes, uchar *slice)
{
  typedef itk::Image<T, 3> ImageType;

  typedef itk::ImageFileReader<ImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(m_fileName[0].toAscii().data());
  typedef itk::NrrdImageIO NrrdIOType;
  NrrdIOType::Pointer nrrdIO = NrrdIOType::New();
  reader->SetImageIO(nrrdIO);

  typedef itk::RegionOfInterestImageFilter<ImageType,ImageType> RegionExtractor;

  ImageType::RegionType region;
  ImageType::SizeType size;
  ImageType::IndexType index;
  index[2] = idx[2];
  index[1] = idx[1];
  index[0] = idx[0];
  size[2] = sz[2];
  size[1] = sz[1];
  size[0] = sz[0];
  region.SetIndex(index);
  region.SetSize(size);
  
  // Extract the relevant sub-region.
  RegionExtractor::Pointer extractor = RegionExtractor::New();
  extractor->SetInput(reader->GetOutput());
  extractor->SetRegionOfInterest(region);
  extractor->Update();
  ImageType *dimg = extractor->GetOutput();
  char *tdata = (char*)(dimg->GetBufferPointer());
  memcpy(slice, tdata, nbytes);
}
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;
}
int main(int argc, char *argv[])
{
	//print help
	if( argc == 1 ) //argv[0]
	{
		PrintHelp(argv);
		return 1;
	}

	if( argc == 2 ) //argv[0] -h
	{
		if( argv[1] == string("-h") || argv[1] == string("-H") || argv[1] == string("-help") )
		{
			PrintHelp(argv);
			return 1;
		}
		else
		{
			cerr<< "For help: "<< argv[0] << " -h" <<endl;
			return 0;
		}
	}

	//tags used to name the converted 3d filename: PatientID_StudyID_StudyDate_Access#_Series#_SeriesDescription.mha
	vector<string> tags;
	tags.push_back("0010|0020");//patientID
	tags.push_back("0020|0010");//studyID
	tags.push_back("0008|0020");//studyDate
	tags.push_back("0008|0050");//access#
	tags.push_back("0020|0011");//series#
	tags.push_back("0008|103e");//series description

	//illegal filename chracters:  \ / : * ? " < > |   , which will be removed from tag value.
	string illegalChars = "\\/:?\"<>|"; 

	//accept output format, specified by -f 
	vector<string> acceptFormat;
	acceptFormat.push_back("mha"); 
	acceptFormat.push_back("nii");
	acceptFormat.push_back("mhd");
	acceptFormat.push_back("nrrd");
	acceptFormat.push_back("hdr");

	//timer start
	const clock_t begin_time = clock();

	//parse arguments
	string dicomDirectory; // -i
	string outputDirectory;// -o
	bool write3D = false; //will be set to true, if outputDirectory is good
	bool writeAllSeries = true; // default, if without -k
	string outputFormat = "mha"; //default, if without -f
	vector<string> seriesKeywords; //record series keywords specified by -f
	string convertedList; //-l
	bool writeConvertedList = false; 

	for (int ac = 1; ac < argc; ac++)
	{
		//-i
		if( argv[ac] == string("-i") || argv[ac] == string("-I"))
		{
			if ( ++ac >= argc ) 
			{
				cerr<< "missing argument for -i" <<endl;
				return 1;
			}
			dicomDirectory = argv[ac]; 
		}

		//-o
		if( argv[ac] == string("-o") || argv[ac] == string("-O") )
		{
			if ( ++ac >= argc ) 
			{
				cerr<< "missing argument for -o" <<endl;
				return 1;
			}
			outputDirectory = argv[ac]; 
		}

		//-f
		if( argv[ac] == string("-f") || argv[ac] == string("-F") )
		{
			if ( ++ac >= argc ) 
			{
				cerr<< "missing argument for -f" <<endl;
				return 1;
			}
			outputFormat = argv[ac]; 
			transform(outputFormat.begin(), outputFormat.end(),outputFormat.begin(), tolower); //to lower case
		}

		//-k
		if ( argv[ac] == string("-k") || argv[ac] == string("-K") ) 
		{
			if ( ++ac >= argc ) 
			{
				cerr<< "missing argument for -k" <<endl;
				return 1;
			}

			//add elements after -f to vector serieskeywords
			string seriesKeyword;
			for( int i=ac; i<argc; i++ )
			{
				seriesKeyword=argv[i];
				//push_back until next option
				if( seriesKeyword == string("-l") || seriesKeyword == string("-i") || seriesKeyword == string("-o") || seriesKeyword == string("-f") )
				{
					break;
				}
				transform(seriesKeyword.begin(), seriesKeyword.end(), seriesKeyword.begin(), tolower);//to lower case
				seriesKeyword = std::regex_replace(seriesKeyword, regex("^ +| +$|( ) +"), "$1");//remove leading,trailing and extra white space
				seriesKeywords.push_back(seriesKeyword);
			}

			if( seriesKeywords.size() > 0 )
			{
				writeAllSeries = false;
			}
		}

		//-l
		if( argv[ac] == string("-l") || argv[ac] == string("-L") )
		{
			if ( ++ac >= argc ) 
			{
				cerr<< "missing argument for -l" <<endl;
				return 1;
			}
			convertedList = argv[ac]; 
		}
	}	

	// Check if dicomDirectory is a directory and exist
	bool exist = itksys::SystemTools::FileExists(dicomDirectory.c_str());
	bool isDir = itksys::SystemTools::FileIsDirectory(dicomDirectory.c_str());
	if ( !(exist && isDir) )
	{
		cerr << "ERROR: " << dicomDirectory << " does not exist or is no directory." << endl;
		return 1;
	}

	//check if outputDirectory is good
	if ( !(outputDirectory.empty()) )
	{
		//check if outputDirectory is a file
		bool isFile = itksys::SystemTools::FileExists(outputDirectory.c_str(),true);
		if ( isFile )
		{
			cerr << "ERROR: " << outputDirectory << " should be a directory!" << endl;
			return 1;
		}
		// Check if outputDirectory exist 
		exist = itksys::SystemTools::FileExists( outputDirectory.c_str() );
		if( !exist ) //create directory is not exist
		{  
			try
			{
				itksys::SystemTools::MakeDirectory( outputDirectory.c_str() );
				cout << outputDirectory << " created." << endl;
			}
			catch (itk::ExceptionObject &ex)
			{
				cout << ex << std::endl;
				return 1;
			}
		}

		//set write3D to ture when outputDirectory is good.
		write3D = true;
	}

	//check if ouput format is accept
	if ( !(find(acceptFormat.begin(), acceptFormat.end(), outputFormat) != acceptFormat.end()) )
	{
		cerr<< "accepted output formats:mha, nii, mhd, nrrd, hdr" <<endl;
		return 1;
	}

	//open convertedList file specified by -l
	ofstream convertedListFile;
	if ( !convertedList.empty() )
	{
		convertedListFile.exceptions ( ofstream::failbit | ofstream::badbit );
		try 
		{
			convertedListFile.open( outputDirectory + string(PATH_SEP) + convertedList, ios::out | ios::app);
			writeConvertedList = true;
		}
		catch (std::ofstream::failure e) 
		{
			cerr << "Exception opening file."<<endl;
			return 1;
		}
	}

	cout<<"Analyzing "<<dicomDirectory<<endl;

	//image type to read 2d dicom image, used to get the dicom tags of patientID,studyId,etc...
	typedef itk::Image< signed short, 2 >  ImageType2D;
	typedef itk::ImageFileReader< ImageType2D >     ReaderType2D;
	ReaderType2D::Pointer reader2D = ReaderType2D::New();

	//image type to write 3d mha image
	typedef signed short    PixelType;
	const unsigned int      Dimension = 3;
	typedef itk::Image< PixelType, Dimension >         ImageType;
	typedef itk::ImageSeriesReader< ImageType >        ReaderType;
	typedef itk::GDCMSeriesFileNames NamesGeneratorType;
	NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();

	ReaderType::Pointer reader = ReaderType::New();
	typedef itk::GDCMImageIO       ImageIOType;
	ImageIOType::Pointer dicomIO = ImageIOType::New();

	nameGenerator->SetRecursive(true);
	nameGenerator->SetUseSeriesDetails(true);
	nameGenerator->AddSeriesRestriction("0008|0021");
	nameGenerator->SetDirectory(dicomDirectory);

	//get all the series (by series UID) under the input folder
	typedef std::vector< std::string >    SeriesIdContainer;
	const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
	SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
	SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();

	//get the correspondence between series UID and PatientID,studyId,studyDate,accessNumber,seriesNumber,seriesDescription
	//key is series UID, vector<string> is PatientID,studyID,studyDate,accessNumber,seriesNumber,seriesDescription
	map< string, vector<string> > seriesUidToOtherStuff; 
	seriesItr = seriesUID.begin();
	while (seriesItr != seriesUID.end())
	{
		string seriesIdentifier = seriesItr->c_str();
		//get file names belong to specific series
		vector< string > fileNames = nameGenerator->GetFileNames(seriesIdentifier);
		vector< string > otherStuff;

		//read tags(PatientID StudyID StudyDate Access# Series# SeriesDescription) value from the first file of each series
		if (!fileNames.empty())
		{
			reader2D->SetFileName(fileNames[0]);
			reader2D->SetImageIO(dicomIO);
			try
			{
				reader2D->UpdateLargestPossibleRegion(); //do not use reader->Update(),since image size is different across series.
			}
			catch (itk::ExceptionObject &ex)
			{
				cout << ex << endl; 
				return 1;
			}

			typedef itk::MetaDataDictionary   DictionaryType;
			const  DictionaryType & dictionary = dicomIO->GetMetaDataDictionary();
			typedef itk::MetaDataObject< std::string > MetaDataStringType;
			DictionaryType::ConstIterator itr = dictionary.Begin();
			DictionaryType::ConstIterator end = dictionary.End();

			for (int i = 0; i < tags.size(); i++)
			{
				string entryId = tags[i];
				DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
				if( tagItr != end )
				{
					MetaDataStringType::ConstPointer entryvalue =dynamic_cast<const MetaDataStringType *>(tagItr->second.GetPointer() );
					if( entryvalue )//entry found
					{
						string tagvalue = entryvalue->GetMetaDataObjectValue();
						tagvalue = regex_replace(tagvalue, regex("^ +| +$|( ) +"), "$1");//remove leading,trailing and extra white space
						otherStuff.push_back(tagvalue);
					}
					else
					{
						otherStuff.push_back("EntryNotFound");
					}
				}
			}//end for
		}//end if (!fileNames.empty())
		seriesUidToOtherStuff[seriesIdentifier] = otherStuff;
		seriesItr++;
	}//end while


	//list series number and description for each patient and access# 
	/*patientID, access#, series#, series descrition hierarchy:
	patientid
	access#
	series#:series description		
	series#:series description
	...
	access#
	series#:series description		
	series#:series description
	...
	patientid
	...
	...
	*/

	//create 2d vector for sorting
	vector<string> vs;
	vector< vector<string> > vvs;
	for( map< string,vector<string> >::iterator ii=seriesUidToOtherStuff.begin(); ii!=seriesUidToOtherStuff.end(); ++ii)
	{
		vector<string> vsNew;
		vs = (*ii).second;
		vsNew.push_back(vs[0]);//patientID
		vsNew.push_back(vs[3]);//access#
		vsNew.push_back(vs[4]);//series#
		vsNew.push_back(vs[5]);//series description
		vvs.push_back(vsNew);
	}

	//sort: patientID and access# by string lexicographical order, series# by integer
	sort(vvs.begin(),vvs.end(),comparator);

	//print series number and description for each patient and access# 
	string patientID;
	string accessNumber;
	vector<string> patientIDVector;
	vector<string> accessNumberVector;
	if ( vvs.size()>0 )
	{
		cout <<dicomDirectory<<" contains the following DICOM Series:"<<endl;
		for( int i = 0; i < vvs.size(); i++)
		{
			patientID = vvs[i][0];
			accessNumber = vvs[i][1];

			if (find(patientIDVector.begin(), patientIDVector.end(), patientID) == patientIDVector.end() ) // a new patientID
			{
				patientIDVector.push_back(patientID);
				cout<<"patient ID: "<<patientID<<endl;
			}
			if (find(accessNumberVector.begin(), accessNumberVector.end(), accessNumber) == accessNumberVector.end() ) // a new accessNumber
			{
				accessNumberVector.push_back(accessNumber);
				cout<<"   "<<"access#: "<<accessNumber<<endl;
			}
			cout<<"      "<<vvs[i][2]<<": "<<vvs[i][3]<<endl; //list series#:series description
		}
	}
	else
	{
		cout << "The directory: "<<dicomDirectory<<" contains no DICOM Series! InputDirectory correct?"<<endl;
		return 0;
	}

	//write 3D volume
	if (write3D)
	{
		typedef std::vector< std::string >   FileNamesContainer;
		FileNamesContainer fileNames; 

		typedef itk::ImageFileWriter< ImageType > WriterType;
		WriterType::Pointer writer = WriterType::New();
		string outFileName;

		seriesItr = seriesUID.begin();
		while (seriesItr != seriesUID.end())
		{
			string seriesIdentifier;
			if (writeAllSeries) //without -k option
			{
				seriesIdentifier = seriesItr->c_str();
			}
			else //with -k option
			{
				//get sereisDescription according to seriesUID
				string seriesDescription = seriesUidToOtherStuff[*seriesItr][5];
				transform(seriesDescription.begin(), seriesDescription.end(), seriesDescription.begin(), tolower);//to lower case

				//check if series Description contains the specified keyword (by -k)
				for( int i = 0; i < seriesKeywords.size(); i++)
				{
					if (seriesDescription.find(seriesKeywords[i]) != string::npos)
					{
						seriesIdentifier = seriesItr->c_str();
					}
				} 
			}//end if (writeAllSeries)

			if ( !seriesIdentifier.empty() )
			{
				//get file names belong to specific series
				fileNames = nameGenerator->GetFileNames(seriesIdentifier);
				reader->SetImageIO(dicomIO);
				reader->SetFileNames(fileNames);

				//get output file name:PatientID_StudyID_StudyDate_Access#_Series#_SeriesDescription
				vector<string> vs = seriesUidToOtherStuff[seriesIdentifier];
				string temp = vs[0]+"_"+vs[1]+"_"+vs[2]+"_"+vs[3]+"_"+vs[4]+"_"+vs[5];
				string tempNew;
				//remove illegal characters
				for (string::iterator it = temp.begin(); it < temp.end(); ++it)
				{
					bool found = illegalChars.find(*it) != string::npos;
					if(!found){
						tempNew=tempNew+(*it);
					}
				}
				//repace space with . . Many series descriptions come with spaces. But, filenames with spaces is not good.
				replace( tempNew.begin(), tempNew.end(), ' ', '.'); 
				//get full path file name
				outFileName = outputDirectory + string(PATH_SEP) + tempNew + "."+outputFormat;

				//write
				writer->SetFileName(outFileName);
				writer->UseCompressionOn();
				writer->SetInput(reader->GetOutput());
				cout << "Writing: " << outFileName << endl;
				try
				{
					writer->Update();
				}
				catch (itk::ExceptionObject &ex)
				{
					cout << ex << std::endl;
					continue;
				}

				//writing converted files full path to convertedList
				if ( writeConvertedList )
				{
					try
					{
						convertedListFile << outFileName <<endl;
					}
					catch (std::ofstream::failure e) 
					{
						cerr << "Exception writing file"<<endl;
					}
				}
			}
			seriesItr++;
		}//end while
	}//end if write3D

	//close convertedList file
	if (convertedListFile.is_open())
	{
		try
		{
			convertedListFile.close();
		}
		catch (std::ofstream::failure e) 
		{
			cerr << "Exception closing file"<<endl;
		}
	}

	//print elasped time
	cout << "Elapsed time: "<<float( clock () - begin_time )/CLOCKS_PER_SEC<<" Seconds";

	return 0;
}
void QtDcmConvert::convert()
{
    if (QtDcmPreferences::instance()->useDcm2nii())
    {
        QString program = QtDcmPreferences::instance()->getDcm2niiPath();
        QStringList arguments;
        arguments << "-x" << "N";
        arguments << "-r" << "N";
        arguments << "-g" << "N";
        arguments << "-o" << d->outputDirectory << d->inputDirectory;
        
        QProcess * process = new QProcess(this);
        process->setStandardOutputFile(d->tempDirectory + QDir::separator() + "logs" + QDir::separator() + d->serieUID + ".txt");
        process->start(program, arguments);
        process->waitForFinished();

        delete process;
    }
    else
    {
        typedef signed short                                PixelType;
        const unsigned int Dimension = 3;
        typedef itk::Image< PixelType, Dimension >          ImageType;
        typedef itk::ImageSeriesReader< ImageType >         ReaderType;
        typedef itk::ImageFileWriter<ImageType>             WriterType;
        typedef itk::GDCMImageIO                            ImageIOType;
        typedef itk::GDCMSeriesFileNames                    NamesGeneratorType;
        typedef std::vector< std::string >                  FileNamesContainer;
        typedef std::vector< std::string >                  SeriesIdContainer;

//     ImageType::Pointer image = 0;

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

        NamesGeneratorType::Pointer inputNames = NamesGeneratorType::New();
        inputNames->SetUseSeriesDetails ( true );
        inputNames->AddSeriesRestriction ( "0008|0021" );
        inputNames->AddSeriesRestriction ( "0020,0037" );
        inputNames->LoadSequencesOn();
        inputNames->LoadPrivateTagsOn();
        inputNames->SetInputDirectory ( d->inputDirectory.toStdString() );
        try
        {
            const SeriesIdContainer & seriesUID = inputNames->GetSeriesUIDs();
            std::string seriesIdentifier = seriesUID.begin()->c_str();
            FileNamesContainer filenames = inputNames->GetFileNames ( seriesIdentifier );

            dicomIO->SetFileName ( filenames.begin()->c_str() );
            try
            {
                dicomIO->ReadImageInformation();
            }
            catch ( itk::ExceptionObject &e )
            {
                qDebug() << e.GetDescription();
                return;
            }

            reader->UseStreamingOn();
            reader->SetFileNames ( filenames );
            reader->SetImageIO ( dicomIO );

            try
            {
                reader->Update();
            }
            catch ( itk::ExceptionObject &excp )
            {
                std::cerr << excp << std::endl;
                return;
            }

//         IteratorType itOut;
//
//         image = reader->GetOutput();
//
//         RegionType region;
//         region.SetSize ( 0, image->GetLargestPossibleRegion().GetSize() [0] );
//         region.SetSize ( 1, image->GetLargestPossibleRegion().GetSize() [1] );
//         region.SetSize ( 2, image->GetLargestPossibleRegion().GetSize() [2] );
//         image->SetRegions ( region );
//         image->Allocate();
//         SpacingType spacing;
//         spacing[0] = image->GetSpacing() [0];
//         spacing[1] = image->GetSpacing() [1];
//         spacing[2] = image->GetSpacing() [2];
//         spacing[3] = 1;
//         image->SetSpacing ( spacing );
//         PointType origin;
//         origin[0] = image->GetOrigin() [0];
//         origin[1] = image->GetOrigin() [1];
//         origin[2] = image->GetOrigin() [2];
//         origin[3] = 0;
//         image->SetOrigin ( origin );
//         DirectionType direction;
//         for ( unsigned int i=0; i<4; i++ )
//             for ( unsigned int j=0; j<4; j++ )
//             {
//                 if ( ( i < 3 ) && ( j < 3 ) )
//                     direction[i][j] = image->GetDirection() [i][j];
//                 else
//                     direction[i][j] = ( i == j ) ? 1 : 0;
//             }
//         image->SetDirection ( direction );
//         itOut = IteratorType ( image, region );
//
//         image->SetMetaDataDictionary ( dicomIO->GetMetaDataDictionary() );
//
//
//         itk::ImageRegionIterator<ImageType> itIn ( image, image->GetLargestPossibleRegion() );
//         while ( !itIn.IsAtEnd() )
//         {
//             itOut.Set ( itIn.Get() );
//             ++itIn;
//             ++itOut;
//         }


            WriterType::Pointer writer = WriterType::New();

            QString completeFilename = d->outputDirectory + QDir::separator() + d->outputFilename;

            writer->SetFileName ( completeFilename.toStdString() );
            writer->SetInput ( reader->GetOutput() );
//         writer->SetInput ( image );

            try
            {
                writer->Update();
            }
            catch ( itk::ExceptionObject &ex )
            {
                std::cout << ex << std::endl;
                return;
            }
        }
        catch ( itk::ExceptionObject &ex )
        {
            std::cout << ex << std::endl;
            return;
        }
    }
}
// ------------------------------------------------------------------------
void DicomParser::loadImages()
{
	// group the series into sa and not sa 
	DicomSeriesList saList;
	DicomSeriesList otherList;

	for(unsigned int i = 0; i < series.size(); i++)
	{
		std::string description = series[i].description;
		QString desc = QString::fromStdString(description);
		
		if(desc.contains("Cine_SA"))
			saList.push_back(series[i]);
		else if(desc.contains("cine_SA"))
			saList.push_back(series[i]);
		else if(desc.contains("Cine_sa"))
			saList.push_back(series[i]);
		else if(desc.contains("Cine_ipat SA"))
			saList.push_back(series[i]);
		//else if(desc.contains("sa"))
			//saList.push_back(series[i]);
		else
			otherList.push_back(series[i]);
	}

	// sort the sa list based on position
	std::sort(saList.begin(), saList.end(), series_sort);
	std::sort(otherList.begin(), otherList.end(), series_sort);


	for(unsigned int i = 0; i < saList.size(); i++)
	{
		seriesAgain.push_back(saList[i]);
	}




	for(unsigned int i = 0; i < otherList.size(); i++)
	{
		seriesAgain.push_back(otherList[i]);
	}


	for(unsigned int i = 0; i < seriesAgain.size(); i++)
	{
		std::string filename = seriesAgain[i].images.front().filename;

		typedef itk::Image<unsigned short,3> ImageType;
		typedef itk::ImageFileReader<ImageType> ReaderType;
		ReaderType::Pointer reader = ReaderType::New();
		reader->SetImageIO(itk::GDCMImageIO::New());
		reader->SetFileName(filename);

		typedef itk::ImageToVTKImageFilter<ImageType> VTKFilterType;
		VTKFilterType::Pointer vtkFilter = VTKFilterType::New();
		vtkFilter->SetInput(reader->GetOutput());
		vtkFilter->Update();


		vtkSmartPointer<vtkImageData> image = 
			vtkSmartPointer<vtkImageData>::New();
		image->DeepCopy(vtkFilter->GetOutput());
		image->Print(std::cout);
		

		vtkSmartPointer<vtkImageSliceMapper> mapper =
			vtkSmartPointer<vtkImageSliceMapper>::New();
		mapper->SetInputData(image);

		vtkSmartPointer<vtkImageSlice> actor = 
			vtkSmartPointer<vtkImageSlice>::New();
		actor->SetMapper(mapper);


		actor->GetProperty()->SetColorLevel(177.48);
		actor->GetProperty()->SetColorWindow(512.04);


		images.push_back(actor);


		
	}

}
        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)
{
	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;

}
Exemple #17
0
bool
NrrdPlugin::setFile(QStringList files)
{
  m_fileName = files;
 
  typedef itk::Image<unsigned char, 3> ImageType;
  typedef itk::ImageFileReader<ImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(m_fileName[0].toAscii().data());

  typedef itk::NrrdImageIO NrrdIOType;
  NrrdIOType::Pointer nrrdIO = NrrdIOType::New();
  reader->SetImageIO(nrrdIO);
  reader->Update();

  itk::ImageIOBase::Pointer imageIO = reader->GetImageIO();

  m_height = imageIO->GetDimensions(0);
  m_width = imageIO->GetDimensions(1);
  m_depth = imageIO->GetDimensions(2);

  m_voxelSizeX = imageIO->GetSpacing(0);
  m_voxelSizeY = imageIO->GetSpacing(1);
  m_voxelSizeZ = imageIO->GetSpacing(2);

  int et = imageIO->GetComponentType();
  if (et == itk::ImageIOBase::UCHAR) m_voxelType = _UChar;
  if (et == itk::ImageIOBase::CHAR) m_voxelType = _Char;
  if (et == itk::ImageIOBase::USHORT) m_voxelType = _UShort;
  if (et == itk::ImageIOBase::SHORT) m_voxelType = _Short;
  if (et == itk::ImageIOBase::INT) m_voxelType = _Int;
  if (et == itk::ImageIOBase::FLOAT) m_voxelType = _Float;

  m_skipBytes = m_headerBytes = 0;

  m_bytesPerVoxel = 1;
  if (m_voxelType == _UChar) m_bytesPerVoxel = 1;
  else if (m_voxelType == _Char) m_bytesPerVoxel = 1;
  else if (m_voxelType == _UShort) m_bytesPerVoxel = 2;
  else if (m_voxelType == _Short) m_bytesPerVoxel = 2;
  else if (m_voxelType == _Int) m_bytesPerVoxel = 4;
  else if (m_voxelType == _Float) m_bytesPerVoxel = 4;

  if (m_4dvol) // do not perform further calculations.
    return true;

  if (m_voxelType == _UChar ||
      m_voxelType == _Char ||
      m_voxelType == _UShort ||
      m_voxelType == _Short)
    {
      findMinMaxandGenerateHistogram();
    }
  else
    {
      findMinMax();
      generateHistogram();
    }

  return true;
}
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;

}
int main() {


    typedef unsigned short    PixelType;
    const unsigned int      Dimension = 3;

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

    typedef itk::VTKImageExport<ImageType> ImageExportType;
    typedef itk::ImageSeriesReader< ImageType >        ReaderType;
    ReaderType::Pointer reader = ReaderType::New();
    typedef itk::GDCMImageIO       ImageIOType;
    ImageIOType::Pointer dicomIO = ImageIOType::New();

    reader->SetImageIO( dicomIO );
    typedef itk::GDCMSeriesFileNames NamesGeneratorType;
    NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();

    nameGenerator->SetUseSeriesDetails( true );
    nameGenerator->AddSeriesRestriction("0008|0021" );
    nameGenerator->SetDirectory( "/Users/mac/BIOMED/Subjects/testSubject");

    typedef std::vector< std::string >    SeriesIdContainer;
    const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
    std::cout << seriesUID.size() << std::endl;
    SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
    SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();
    while( seriesItr != seriesEnd )
    {
        std::cout << seriesItr->c_str() << std::endl;
        seriesItr++;
    }
    std::string seriesIdentifier;
    seriesIdentifier = seriesUID.begin()->c_str();
    std::cout << seriesIdentifier.c_str() << std::endl;

    typedef std::vector< std::string >   FileNamesContainer;
    FileNamesContainer fileNames;
    fileNames = nameGenerator->GetFileNames( seriesIdentifier );

    reader->SetFileNames( fileNames );
    try
    {
        reader->Update();
    }
    catch (itk::ExceptionObject &ex)
    {
        std::cout << ex << std::endl;
    }

//------------------------------------------------------------------------
// ITK to VTK pipeline connection.
//------------------------------------------------------------------------

// Create the itk::VTKImageExport instance and connect it to the
// itk::CurvatureFlowImageFilter.
    ImageExportType::Pointer exporter = ImageExportType::New();
    exporter->SetInput(reader->GetOutput());
    exporter->Update();

// Create the vtkImageImport and connect it to the
// itk::VTKImageExport instance.
    vtkImageImport* importer = vtkImageImport::New();
    ConnectPipelines(exporter, importer);

//------------------------------------------------------------------------
// VTK pipeline.
//------------------------------------------------------------------------


    //Demo Display DICOM Image
    /*
    string folder = "/Users/mac/BIOMED/Subjects/testSubject";
    // Read all the DICOM files in the specified directory.
    vtkSmartPointer<vtkDICOMImageReader> reader2 =
            vtkSmartPointer<vtkDICOMImageReader>::New();
    reader2->SetDirectoryName(folder.c_str());
    reader2->Update();
*/

    vtkSmartPointer<vtkImageSliceMapper> imageSliceMapper = vtkSmartPointer<vtkImageSliceMapper>::New();
    imageSliceMapper->SetInputConnection(importer->GetOutputPort());

    //imageSliceMapper->SetInputData(importer->GetOutput());
    imageSliceMapper->Update();


    vtkSmartPointer<vtkImageSlice> imageSlice = vtkSmartPointer<vtkImageSlice>::New();
    imageSlice->SetMapper(imageSliceMapper);



    vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper =
            vtkSmartPointer<vtkSmartVolumeMapper>::New();
    volumeMapper->SetBlendModeToComposite();
    volumeMapper->SetInputConnection(importer->GetOutputPort());

    vtkSmartPointer<vtkVolumeProperty> volumeProperty =
            vtkSmartPointer<vtkVolumeProperty>::New();
    volumeProperty->ShadeOff();
    volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);



    // Setup renderers
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddViewProp(imageSlice);
    renderer->ResetCamera();
    renderer->SetBackground(0.1,0.4,0.2);

    // Setup render window
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->SetSize(500, 500);
    renderWindow->AddRenderer(renderer);



    vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(volumeMapper);
    volume->SetProperty(volumeProperty);
    renderer->AddViewProp(volume);



    renderer->ResetCamera();
    volumeMapper->SetRequestedRenderModeToRayCast();
    volumeMapper->SetBlendModeToMinimumIntensity();

    renderWindow->Render();

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();

    // Render and start interaction
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderWindowInteractor->Initialize();

    renderWindowInteractor->Start();


    return 0;
}
Exemple #20
0
int main(int argc, char *argv[])
{
    srand (time(NULL));
    
	if (argc == 1)
    {
        help();
        return EXIT_FAILURE;
    }
    string inputFilename = "", outputPath = "", outputFilenameBinary = "", outputFilenameMesh = "", outputFilenameBinaryCSF = "", outputFilenameMeshCSF = "", outputFilenameAreas = "", outputFilenameAreasCSF = "", outputFilenameCenterline = "", outputFilenameCenterlineBinary = "", inputCenterlineFilename = "", initMaskFilename = "";
    double typeImageFactor = 0.0, initialisation = 0.5;
    int downSlice = -10000, upSlice = 10000;
    string suffix;
	bool input_dicom = false, output_detection = false, output_mesh = false, output_centerline_binary = false, output_centerline_coord = false, output_cross = false, init_with_centerline = false, init_with_mask = false, verbose = false, output_init_tube = false, completeCenterline = false, init_validation = false, low_res_mesh = false, CSF_segmentation = false;
	int gapInterSlices = 4, nbSlicesInitialisation = 5;
	double radius = 4.0;
    int numberOfPropagationIteration = 200;
    double maxDeformation = 0.0, maxArea = 0.0, minContrast = 50.0, tradeoff_d;
	bool tradeoff_d_bool = false;
    for (int i = 0; i < argc; ++i) {
        if (strcmp(argv[i],"-i")==0) {
            i++;
            inputFilename = argv[i];
        }
        else if (strcmp(argv[i],"-i-dicom")==0) {
            i++;
            //inputFilename = argv[i];
            //input_dicom = true;
        }
        else if (strcmp(argv[i],"-o")==0) {
            i++;
            outputPath = argv[i];
        }
        else if (strcmp(argv[i],"-t")==0) {
            i++;
            if (strcmp(argv[i],"t1")==0) {
				typeImageFactor = -1.0;
				if (verbose) cout << endl << "WARNING: be sure your image is a T1-weighted image." << endl << endl;
			}
            else if (strcmp(argv[i],"t2")==0) {
				typeImageFactor = 1.0;
				if (verbose) cout << endl << "WARNING: be sure your image is a T2-weighted image." << endl << endl;
			}
            else {
				cout << "Error: Invalid type or image (need to be \"t1\" or \"t2\")" << endl << endl;
				help();
                return EXIT_FAILURE;
			}
        }
        else if (strcmp(argv[i],"-init")==0) {
            i++;
            initialisation = atof(argv[i]);
        }
        else if (strcmp(argv[i],"-down")==0) {
            i++;
            downSlice = atoi(argv[i]);
        }
        else if (strcmp(argv[i],"-up")==0) {
            i++;
            upSlice = atoi(argv[i]);
        }
		else if (strcmp(argv[i],"-detect-display")==0) {
            output_detection = true;
        }
		else if (strcmp(argv[i],"-mesh")==0) {
            output_mesh = true;
        }
		else if (strcmp(argv[i],"-centerline-binary")==0) {
            output_centerline_binary = true;
        }
		else if (strcmp(argv[i],"-centerline-coord")==0) {
            output_centerline_coord = true;
        }
		else if (strcmp(argv[i],"-cross")==0) {
            output_cross = true;
        }
		else if (strcmp(argv[i],"-detect-n")==0) {
            i++;
            nbSlicesInitialisation = atoi(argv[i]);
        }
		else if (strcmp(argv[i],"-detect-gap")==0) {
            i++;
            gapInterSlices = atoi(argv[i]);
        }
		else if (strcmp(argv[i],"-detect-radius")==0) {
            i++;
            radius = atof(argv[i]);
        }
		else if (strcmp(argv[i],"-init-centerline")==0) {
            i++;
            inputCenterlineFilename = argv[i];
            init_with_centerline = true;
        }
        else if (strcmp(argv[i],"-nbiter")==0) {
            i++;
            numberOfPropagationIteration = atoi(argv[i]);
        }
        else if (strcmp(argv[i],"-init-mask")==0) {
            i++;
            initMaskFilename = argv[i];
            init_with_mask = true;
        }
        else if (strcmp(argv[i],"-init-tube")==0) {
            output_init_tube = true;
        }
		else if (strcmp(argv[i],"-init-validation")==0) {
            init_validation = true;
        }
        else if (strcmp(argv[i],"-low-resolution-mesh")==0) {
            low_res_mesh = true;
        }
        else if (strcmp(argv[i],"-max-deformation")==0) {
            i++;
            maxDeformation = atof(argv[i]);
        }
        else if (strcmp(argv[i],"-max-area")==0) {
            i++;
            maxArea = atof(argv[i]);
        }
        else if (strcmp(argv[i],"-min-contrast")==0) {
            i++;
            minContrast = atof(argv[i]);
        }
		else if (strcmp(argv[i],"-d")==0) {
            i++;
            tradeoff_d = atof(argv[i]);
			tradeoff_d_bool = true;
        }
        else if (strcmp(argv[i],"-CSF")==0) {
            CSF_segmentation = true;
            if (maxArea == 0.0) maxArea = 120;
            if (maxDeformation == 0.0) maxDeformation = 2.5;
        }
		else if (strcmp(argv[i],"-verbose")==0) {
            verbose = true;
        }
        else if (strcmp(argv[i],"-help")==0) {
            help();
            return EXIT_FAILURE;
        }
    }
    if (inputFilename == "")
    {
        cerr << "Input filename or folder (if DICOM) not provided" << endl;
		help();
        return EXIT_FAILURE;
    }
    if (typeImageFactor == 0)
    {
        cerr << "Error: The type of contrast not provided (option -t)" << endl;
		help();
        return EXIT_FAILURE;
    }
    
    // output files must have the same extension as input file
    string nii=".nii", niigz=".nii.gz"; suffix=niigz;
    size_t pos = inputFilename.find(niigz);
    if (pos == string::npos) {
        pos = inputFilename.find(nii);
        suffix = nii;
    }
    if (outputPath!="" && outputPath.compare(outputPath.length()-1,1,"/")) outputPath += "/"; // add "/" if missing
    outputFilenameBinary = outputPath+"segmentation_binary"+suffix;
    outputFilenameMesh = outputPath+"segmentation_mesh.vtk";
    outputFilenameBinaryCSF = outputPath+"segmentation_CSF_binary"+suffix;
    outputFilenameMeshCSF = outputPath+"segmentation_CSF_mesh.vtk";
    outputFilenameAreas = outputPath+"cross_sectional_areas.txt";
    outputFilenameAreasCSF = outputPath+"cross_sectional_areas_CSF.txt";
    outputFilenameCenterline = outputPath+"segmentation_centerline.txt";
    outputFilenameCenterlineBinary = outputPath+"segmentation_centerline_binary"+suffix;
    // if output path doesn't exist, we create it
    if (outputPath!="") itk::FileTools::CreateDirectory(outputPath.c_str());
    
    // Image reading - image can be T1 or T2 (or Tx-like) depending on contrast between spinal cord and CSF
	// typeImageFactor depend of contrast type and is equal to +1 when CSF is brighter than spinal cord and equal to -1 inversely
    ImageType::Pointer initialImage, image = ImageType::New();
    
    if (input_dicom)
    {
        /*ImageIOType::Pointer gdcmIO = ImageIOType::New();
        InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
        inputNames->SetInputDirectory( inputFilename );
        
        const DICOMReaderType::FileNamesContainer & filenames = inputNames->GetInputFileNames();
        
        DICOMReaderType::Pointer reader = DICOMReaderType::New();
        reader->SetImageIO( gdcmIO );
        reader->SetFileNames( filenames );
        try
        {
            reader->Update();
        } catch (itk::ExceptionObject &excp) {
            std::cerr << "Exception thrown while reading the DICOM series" << std::endl;
            std::cerr << excp << std::endl;
            return EXIT_FAILURE;
        }
        initialImage = reader->GetOutput();*/
    }
    else
    {
        ReaderType::Pointer reader = ReaderType::New();
        itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
        reader->SetImageIO(io);
        reader->SetFileName(inputFilename);
        try {
            reader->Update();
        } catch( itk::ExceptionObject & e ) {
            cerr << "Exception caught while reading input image" << endl;
            cerr << e << endl;
            return EXIT_FAILURE;
        }
        initialImage = reader->GetOutput();
    }
    
    // Change orientation of input image to AIL. Output images will have the same orientation as input image
    OrientImage<ImageType> orientationFilter;
    orientationFilter.setInputImage(initialImage);
    orientationFilter.orientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIL);
    initialImage = orientationFilter.getOutputImage();
	
	// Crop image if it is too large in left-right direction. No need to compute the initialization on the whole image. We assume the spinal cord is included in a 5cm large region.
	ImageType::SizeType desiredSize = initialImage->GetLargestPossibleRegion().GetSize();
    ImageType::SpacingType spacingI = initialImage->GetSpacing();
	if (desiredSize[2]*spacingI[2] > 60 && !init_with_mask && !init_with_centerline)
	{
		SymmetricalCropping symCroppingFilter;
        symCroppingFilter.setInputImage(initialImage);
		symCroppingFilter.setInitSlice(initialisation);
		int crop_slice = -1;
		try {
			crop_slice = symCroppingFilter.symmetryDetection();
		} catch(exception & e) {
		    cerr << "Exception caught while computing symmetry" << endl;
            cerr << e.what() << endl;
            return EXIT_FAILURE;
		}
		if (crop_slice != -1) {
			if (verbose) cout << "Cropping input image in left-right direction around slice = " << crop_slice << endl;
			image = symCroppingFilter.cropping();
		} else {
			if (verbose) cout << "Image non cropped for symmetry" << endl;
			image = initialImage;
		}
	}
	else image = initialImage;
    
	// Intensity normalization
	RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
	rescaleFilter->SetInput(image);
	rescaleFilter->SetOutputMinimum(0);
	rescaleFilter->SetOutputMaximum(1000);
    try {
        rescaleFilter->Update();
    } catch( itk::ExceptionObject & e ) {
        cerr << "Exception caught while normalizing input image " << endl;
        cerr << e << endl;
        return EXIT_FAILURE;
    }
	image = rescaleFilter->GetOutput();
	
	// computing magnitude and direction of gradient image
	GradientMFilterType::Pointer gradientMagnitudeFilter = GradientMFilterType::New();
	gradientMagnitudeFilter->SetInput(image);
	try {
		gradientMagnitudeFilter->Update();
	} catch( itk::ExceptionObject & e ) {
		cerr << "Exception caught while updating gradientMagnitudeFilter " << endl;
		cerr << e << endl;
        return EXIT_FAILURE;
	}
	ImageType::Pointer imageGradient = gradientMagnitudeFilter->GetOutput();
    
	VectorGradientFilterType::Pointer gradientMapFilter = VectorGradientFilterType::New();
	gradientMapFilter->SetInput( image );
	try {
		gradientMapFilter->Update();
	} catch( itk::ExceptionObject & e ) {
		cerr << "Exception caught while updating gradientMapFilter " << endl;
		cerr << e << endl;
        return EXIT_FAILURE;
	}
	GradientImageType::Pointer imageVectorGradient = gradientMapFilter->GetOutput();
    
	// Creation of 3D image with origin, orientation and scaling, containing original image, gradient image, vector gradient image
	ImageType::SizeType regionSize = image->GetLargestPossibleRegion().GetSize();
	ImageType::PointType origineI = image->GetOrigin();
	CVector3 origine = CVector3(origineI[0],origineI[1],origineI[2]);
	ImageType::DirectionType directionI = image->GetInverseDirection();
	CVector3	directionX = CVector3(directionI[0][0],directionI[0][1],directionI[0][2]),
    directionY = CVector3(directionI[1][0],directionI[1][1],directionI[1][2]),
    directionZ = CVector3(directionI[2][0],directionI[2][1],directionI[2][2]);
	CVector3 spacing = CVector3(spacingI[0],spacingI[1],spacingI[2]);
	Image3D* image3DGrad = new Image3D(imageVectorGradient,regionSize[0],regionSize[1],regionSize[2],origine,directionX,directionY,directionZ,spacing,typeImageFactor);
	image3DGrad->setImageOriginale(initialImage);
	image3DGrad->setCroppedImageOriginale(image);
	image3DGrad->setImageMagnitudeGradient(imageGradient);
    
    
	/******************************************
     // Initialization of Propagated Deformable Model of Spinal Cord
     ******************************************/
	int radialResolution, axialResolution, numberOfDeformIteration = 3;
	double axialStep, propagationLength = 800.0;
	// Definition of parameters for T1 and T2 images. T1 need better resolution to provide accurate segmentation.
    if (typeImageFactor == 1.0) { // T2
        radialResolution = 15;
        axialResolution = 3;
        axialStep = 6.0;
    }
    else { // T1
        radialResolution = 20; //30
        axialResolution = 3; //5
        axialStep = 6.0; //8
    }
    
    CVector3 point, normal1, normal2; // normal1 and normal2 and normals in both direction from initial point
    double stretchingFactor = 1.0;
    vector<CVector3> centerline;
    
    if (init_with_centerline)
    {
        if (verbose) cout << "Initialization - using given centerline" << endl;
        centerline = extractCenterline(inputCenterlineFilename);
        if (centerline.size() == 0) return EXIT_FAILURE;
    }
    else if (init_with_mask)
    {
        if (verbose) cout << "Initialization - using given mask" << endl;
        bool result_init = extractPointAndNormalFromMask(initMaskFilename, point, normal1, normal2);
        if (!result_init) return EXIT_FAILURE;
        if (verbose) {
            cout << "Point = " << point << endl;
            cout << "Normal 1 = " << normal1 << endl;
            cout << "Normal 2 = " << normal2 << endl;
        }
    }
    else
    {
        bool isSpinalCordDetected = false;
        int countFailure = 0;
        double step = 0.025; // step of displacement in pourcentage of the image
        do
        {
            if (verbose) cout << "Initialization - spinal cord detection on axial slices" << endl;
            Initialisation init(image,typeImageFactor);
            init.setVerbose(verbose);
            init.setGap(gapInterSlices); // gap between slices is necessary to provide good normals
            init.setRadius(radius); // approximate radius of spinal cord. This parameter is used to initiate Hough transform
            init.setNumberOfSlices(nbSlicesInitialisation);
            
            // if the initialization fails at the first position in the image, an other spinal cord detection process is launch higher.
            int d = rand() % 2; if (d==0) d = -1;
            isSpinalCordDetected = init.computeInitialParameters(initialisation+(double)countFailure*step*(double)d);
            //if (!isSpinalCordDetected) isSpinalCordDetected = init.computeInitialParameters(0.7);
            if(isSpinalCordDetected)
            {
                if (output_detection) init.savePointAsAxialImage(image,outputPath+"result_detection.png");
                
                init.getPoints(point,normal1,normal2,radius,stretchingFactor);
                if (normal2 == CVector3::ZERO) normal2 = -normal1;
                if (verbose) {
                    cout << "Initialization - Spinal Cord Detection:" << endl;
                    cout << "Point = " << point << endl;
                    cout << "Normal 1 = " << normal1 << endl;
                    cout << "Normal 2 = " << normal2 << endl;
                    cout << "Radius = " << radius << endl;
                }
                
				if(init_validation)
				{
					// Definition of discrimination surface for the validation of the spinal cord detection module
					double K_T1 = 15.7528, K_T2 = 3.2854;
					CVector3 L_T1 = CVector3(-0.0762,-2.5921,0.3472), L_T2 = CVector3(-0.0022,-1.2995,0.4909);
					CMatrix3x3 Q_T1, Q_T2;
					Q_T1[0] = 0.0; Q_T1[1] = 0.0; Q_T1[2] = 0.0; Q_T1[3] = 0.0; Q_T1[4] = 0.1476; Q_T1[5] = 0.0; Q_T1[6] = 0.0; Q_T1[7] = 0.0; Q_T1[8] = 0.6082;
					Q_T2[0] = 0.0; Q_T2[1] = 0.0; Q_T2[2] = 0.0; Q_T2[3] = 0.0; Q_T2[4] = 0.0687; Q_T2[5] = 0.0; Q_T2[6] = 0.0; Q_T2[7] = 0.0; Q_T2[8] = 0.3388;
					double contrast = 0.0, mean_distance = 0.0, std_distance = 0.0;
                
					// validation of the spinal cord detetion
					int *sizeDesired = new int[3];
					double *spacingDesired = new double[3];
					sizeDesired[0] = 61; sizeDesired[1] = 61; sizeDesired[2] = 11;
					spacingDesired[0] = 0.5; spacingDesired[1] = 0.5; spacingDesired[2] = 0.5;
					SCRegion* spinal_cord_verif = new SCRegion();
					spinal_cord_verif->setSize(sizeDesired);
					spinal_cord_verif->setSpacing(spacingDesired);
					spinal_cord_verif->setOrigin(point[0],point[1],point[2]);
					spinal_cord_verif->setNormal(normal1[0],normal1[1],normal1[2]);
					spinal_cord_verif->setFactor(typeImageFactor);
					try {
						spinal_cord_verif->readImage(initialImage);
						spinal_cord_verif->createImage();
						contrast = spinal_cord_verif->computeContrast(mean_distance,std_distance,15);
					} catch (string const& e) {
						cerr << e << endl;
						contrast = -1.0;
					}
                
					CVector3 vec = CVector3(contrast,mean_distance,std_distance);
					double discrim = 0.0;
					if (typeImageFactor == -1) // if T1
					{
						CVector3 temp = vec*Q_T1;
						double quad = 0.0;
						for(int r=0; r<3; r++) {
							quad += temp[r]*vec[r];
						}
						discrim = K_T1 + vec*L_T1 + quad;
					}
					else{
						CVector3 temp = vec*Q_T2;
						double quad = 0.0;
						for(int r=0; r<3; r++) {
							quad += temp[r]*vec[r];
						}
						discrim = K_T2 + vec*L_T2 + quad;
					}
                
					if (discrim > 0.0)
					{
						countFailure++;
						isSpinalCordDetected = false;
						if (verbose) cout << "WARNING: Bad initialization. Attempt to locate spinal cord at an other level." << endl << endl;
					}
					else
					{
						isSpinalCordDetected = true;
					}
					delete sizeDesired, spacingDesired, spinal_cord_verif;
				}
				else {
					isSpinalCordDetected = true;
				}
            } else {
                countFailure++;
            }
        }
        while (!isSpinalCordDetected && countFailure<10);
        if (!isSpinalCordDetected)
        {
            cerr << "Error: Enable to detect the spinal cord. Please provide the initial position and orientation of the spinal cord (-init, -init-mask)" << endl;
            return EXIT_FAILURE;
        }
    }
    
	/******************************************
     // Launch of Propagated Deformable Model of Spinal Cord. Propagation have to be done in both direction
     ******************************************/
	PropagatedDeformableModel* prop = new PropagatedDeformableModel(radialResolution,axialResolution,radius,numberOfDeformIteration,numberOfPropagationIteration,axialStep,propagationLength);
    if (maxDeformation != 0.0) prop->setMaxDeformation(maxDeformation);
    if (maxArea != 0.0) prop->setMaxArea(maxArea);
    prop->setMinContrast(minContrast);
	prop->setInitialPointAndNormals(point,normal1,normal2);
    prop->setStretchingFactor(stretchingFactor);
	prop->setUpAndDownLimits(downSlice,upSlice);
	prop->setImage3D(image3DGrad);
    if (init_with_centerline) {
        prop->propagationWithCenterline();
        for (unsigned int k=0; k<centerline.size(); k++) prop->addPointToCenterline(centerline[k]);
        if (initialisation <= 1) prop->setInitPosition(initialisation);
    }
	if (tradeoff_d_bool) {
		prop->setTradeOffDistanceFeature(tradeoff_d);
	}
    prop->setVerbose(verbose);
	prop->computeMeshInitial();
    if (output_init_tube) {
        SpinalCord *tube1 = prop->getInitialMesh(), *tube2 = prop->getInverseInitialMesh();
        tube1->save(outputPath+"InitialTube1.vtk");
        tube2->save(outputPath+"InitialTube2.vtk");
    }
	
	prop->adaptationGlobale(); // Propagation
	// Saving low resolution mesh
	if (low_res_mesh)
    {
        SpinalCord *meshOutputLowResolution = prop->getOutput();
        meshOutputLowResolution->save(outputPath+"segmentation_mesh_low_resolution.vtk",initialImage);
        //meshOutput->computeCenterline(true,path+"LowResolution");
        //meshOutput->computeCrossSectionalArea(true,path+"LowResolution");
        //image3DGrad->TransformMeshToBinaryImage(meshOutput,path+"LowResolution",orientationFilter.getInitialImageOrientation());
        //meshOutput->saveCenterlineAsBinaryImage(initialImage,path+"LowResolution",orientationFilter.getInitialImageOrientation());
    }
    
	/******************************************
     // High Resolution Deformation
     ******************************************/
    prop->rafinementGlobal();
	SpinalCord* meshOutputFinal = prop->getOutputFinal();
	if (output_mesh) meshOutputFinal->save(outputFilenameMesh,initialImage);
	if (output_centerline_coord) meshOutputFinal->computeCenterline(true,outputFilenameCenterline,true);
	if (output_cross) meshOutputFinal->computeCrossSectionalArea(true,outputFilenameAreas,true,image3DGrad);
	image3DGrad->TransformMeshToBinaryImage(meshOutputFinal,outputFilenameBinary,orientationFilter.getInitialImageOrientation());
	if (output_centerline_binary) meshOutputFinal->saveCenterlineAsBinaryImage(initialImage,outputFilenameCenterlineBinary,orientationFilter.getInitialImageOrientation());
    
	if (verbose) {
		double lengthPropagation = meshOutputFinal->getLength();
		cout << "Total propagation length = " << lengthPropagation << " mm" << endl;
	}
    
    
    
    if (CSF_segmentation)
    {
        /******************************************
         // Launch of Propagated Deformable Model on the CSF. Propagation have to be done in both direction
         ******************************************/
        double factor_CSF = 2;
        PropagatedDeformableModel* prop_CSF = new PropagatedDeformableModel(radialResolution,axialResolution,radius*factor_CSF,numberOfDeformIteration,numberOfPropagationIteration,axialStep,propagationLength);
        if (maxDeformation != 0.0) prop_CSF->setMaxDeformation(maxDeformation*factor_CSF);
        if (maxArea != 0.0) prop_CSF->setMaxArea(maxArea*factor_CSF*2);
        prop->setMinContrast(minContrast);
        prop_CSF->setInitialPointAndNormals(point,normal1,normal2);
        prop_CSF->setStretchingFactor(stretchingFactor);
        prop_CSF->setUpAndDownLimits(downSlice,upSlice);
        image3DGrad->setTypeImageFactor(-image3DGrad->getTypeImageFactor());
        prop_CSF->setImage3D(image3DGrad);
        if (init_with_centerline) {
            prop_CSF->propagationWithCenterline();
            for (unsigned int k=0; k<centerline.size(); k++) prop->addPointToCenterline(centerline[k]);
            if (initialisation <= 1) prop->setInitPosition(initialisation);
        }
        prop_CSF->setVerbose(verbose);
        prop_CSF->computeMeshInitial();
        if (output_init_tube) {
            SpinalCord *tube1 = prop_CSF->getInitialMesh(), *tube2 = prop_CSF->getInverseInitialMesh();
            tube1->save(outputPath+"InitialTubeCSF1.vtk");
            tube2->save(outputPath+"InitialTubeCSF2.vtk");
        }
        
        prop_CSF->adaptationGlobale(); // Propagation
        // Saving low resolution mesh
        if (low_res_mesh)
        {
            SpinalCord *meshOutputLowResolution = prop_CSF->getOutput();
            meshOutputLowResolution->save(outputPath+"segmentation_CSF_mesh_low_resolution.vtk",initialImage);
            //meshOutput->computeCenterline(true,path+"LowResolution");
            //meshOutput->computeCrossSectionalArea(true,path+"LowResolution");
            //image3DGrad->TransformMeshToBinaryImage(meshOutput,path+"LowResolution",orientationFilter.getInitialImageOrientation());
            //meshOutput->saveCenterlineAsBinaryImage(initialImage,path+"LowResolution",orientationFilter.getInitialImageOrientation());
        }
        
        /******************************************
         // High Resolution Deformation
         ******************************************/
        prop_CSF->rafinementGlobal();
        SpinalCord* meshOutputFinal = prop_CSF->getOutputFinal();
        if (output_mesh) meshOutputFinal->save(outputFilenameMeshCSF,initialImage);
        if (output_cross) meshOutputFinal->computeCrossSectionalArea(true,outputFilenameAreasCSF,true,image3DGrad);
        image3DGrad->TransformMeshToBinaryImage(meshOutputFinal,outputFilenameBinaryCSF,orientationFilter.getInitialImageOrientation());
        
        if (verbose) {
            double lengthPropagation = meshOutputFinal->getLength();
            cout << "Total propagation length = " << lengthPropagation << " mm" << endl;
        }
        delete prop_CSF;
    }
    
    
	
	delete image3DGrad, prop;
    return EXIT_SUCCESS;
}
bool itkDataTensorImageReaderBase::read (const QString &path)
{
    if (this->io.IsNull())
        return false;
	
    this->readInformation ( path );
	
    qDebug() << "Read with: " << this->identifier();

    if (medAbstractData *medData = dynamic_cast<medAbstractData*>(this->data()) ) {
      
        if (medData->identifier()=="itkDataTensorImageDouble3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 6>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	    
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 9>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}

	else if (medData->identifier()=="itkDataTensorImageFloat3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 6>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }
	    
	    medData->setData (tensors);
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 9>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}
	else {
	  qDebug() << "Unsupported data type";
	  return false;
	}
    }
    else {
      qDebug() << "No data set or could not create one";
      return false;
    }

    return true;
    
}
Exemple #22
0
vector<CVector3> extractCenterline(string filename)
{
    vector<CVector3> result;
    
    string nii=".nii", niigz=".nii.gz", txt=".txt", suffix="";
    size_t pos_niigz = filename.find(niigz), pos_nii = filename.find(nii), pos_txt = filename.find(txt);
    if (pos_niigz != string::npos || pos_nii != string::npos)
    {
        ReaderType::Pointer reader = ReaderType::New();
        itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
        reader->SetImageIO(io);
        reader->SetFileName(filename);
        try {
            reader->Update();
        } catch( itk::ExceptionObject & e ) {
            cerr << "Exception caught while reading centerline input image " << endl;
            cerr << e << endl;
        }
        ImageType::Pointer image_centerline = reader->GetOutput();
        
        OrientImage<ImageType> orientationFilter;
        orientationFilter.setInputImage(image_centerline);
        orientationFilter.orientation(itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIL);
        image_centerline = orientationFilter.getOutputImage();
        
        ImageType::IndexType ind;
        itk::Point<double,3> point;
        ImageIterator it( image_centerline, image_centerline->GetRequestedRegion() );
        it.GoToBegin();
        while(!it.IsAtEnd())
        {
            if (it.Get()!=0)
            {
                ind = it.GetIndex();
                image_centerline->TransformIndexToPhysicalPoint(ind, point);
                bool added = false;
                if (result.size() == 0) {
                    result.push_back(CVector3(point[0],point[1],point[2]));
                    added = true;
                }
                else {
                    for (vector<CVector3>::iterator it=result.begin(); it!=result.end(); it++) {
                        if (point[2] < (*it)[2]) {
                            result.insert(it, CVector3(point[0],point[1],point[2]));
                            added = true;
                            break;
                        }
                    }
                }
                if (!added) result.push_back(CVector3(point[0],point[1],point[2]));
            }
            ++it;
        }
        
        /*// spline approximation to produce correct centerline
        
        double range = result.size()/4.0 ;
        const unsigned int ParametricDimension = 1; const unsigned int DataDimension = 3;
        typedef double RealType;
        typedef itk::Vector<RealType, DataDimension> VectorType; typedef itk::Image<VectorType, ParametricDimension> ImageType;
        typedef itk::PointSet <VectorType , ParametricDimension > PointSetType; PointSetType::Pointer pointSet = PointSetType::New();
        // Sample the helix.
        int nb = result.size();
        for (unsigned long i=0; i<nb; i++) {
            PointSetType::PointType point; point[0] = (double)i/(double)(nb-1);
            pointSet ->SetPoint( i, point );
            VectorType V;
            V[0] = result[i][0]; V[1] = result[i][1]; V[2] = result[i][2];
            pointSet ->SetPointData( i, V );
        }
        
        typedef itk::BSplineScatteredDataPointSetToImageFilter <PointSetType , ImageType > FilterType;
        FilterType::Pointer filter = FilterType::New();
        ImageType::SpacingType spacing; spacing.Fill( 1.0 ); ImageType::SizeType size; size.Fill( 2.0); ImageType::PointType origin; origin.Fill( 0.0 );
        ImageType::RegionType region(size); FilterType::ArrayType closedim; closedim.Fill(0);
        filter->SetSize( size ); filter->SetOrigin( origin ); filter->SetSpacing( spacing ); filter->SetInput( pointSet );
        int splineOrder = 3; filter->SetSplineOrder( splineOrder ); FilterType::ArrayType ncps;
        ncps.Fill( splineOrder + 1 ); filter->SetNumberOfControlPoints( ncps ); filter->SetNumberOfLevels( 5 ); filter->SetGenerateOutputImage( false );
        try
        { filter->Update();
        } catch( itk::ExceptionObject & e ) {
            std::cerr << "Exception caught while reading input image " << std::endl;
            std::cerr << e << std::endl;
        }
        
        typedef itk::BSplineControlPointImageFunction < ImageType, double > BSplineType;
        BSplineType::Pointer bspline = BSplineType::New();
        bspline->SetSplineOrder(filter->GetSplineOrder());
        bspline->SetOrigin(origin);
        bspline->SetSpacing(spacing);
        bspline->SetSize(size);
        bspline->SetInputImage(filter->GetPhiLattice());
        
        result.clear();
        for (double i=0; i<=2.0*range; i++) {
            PointSetType::PointType point; point[0] = i/(2.0*range);
            VectorType V = bspline->Evaluate( point );
            result.push_back(CVector3(V[0],V[1],V[2]));
        }*/
        
    }
    else if (pos_txt != string::npos)
    {
        ifstream myfile;
        string l;
        double x, y, z;
        CVector3 point, pointPrecedent;
        int i = 0;
        myfile.open(filename.c_str());
        if (myfile.is_open())
        {
            while (myfile.good())
            {
                getline(myfile,l);
                stringstream ss(l);
                ss >> x >> z >> y;
                point = CVector3(x,y,z);
                if ((point-pointPrecedent).Norm() > 0) {
                    pointPrecedent = point;
                    //point[1] = -point[1];
                    result.push_back(point);
                }
                i++;
            }
        }
        myfile.close();
    }
Exemple #23
0
int main(int argc, char *argv[])
{
    printf("STARTING\n");
    srand (time(NULL));

    if (argc == 1)
    {
        help();
        return EXIT_FAILURE;
    }

    // Initialization of parameters
    string inputFilename = "", outputPath = "", outputFilenameBinary = "", outputFilenameMesh = "", outputFilenameBinaryCSF = "", outputFilenameMeshCSF = "", outputFilenameAreas = "", outputFilenameAreasCSF = "", outputFilenameCenterline = "", outputFilenameCenterlineBinary = "", inputCenterlineFilename = "", initMaskFilename = "";
    double typeImageFactor = 0.0, initialisation = 0.5;
    int downSlice = -10000, upSlice = 10000;
    string suffix;
    bool input_dicom = false, output_detection = false, output_detection_nii = false, output_mesh = false, output_centerline_binary = false, output_centerline_coord = false, output_cross = false, init_with_centerline = false, init_with_mask = false, verbose = false, output_init_tube = false, completeCenterline = false, init_validation = false, low_res_mesh = false, CSF_segmentation = false;
    int gapInterSlices = 4, nbSlicesInitialisation = 5;
    double radius = 4.0;
    int numberOfPropagationIteration = 200;
    double maxDeformation = 0.0, maxArea = 0.0, minContrast = 50.0, tradeoff_d = 25, tradeoff_K = 200;
    bool tradeoff_d_bool = false;
    int nbiter_GGVF = 2;

    // Initialization with Vesselness Filter and Minimal Path
    bool init_with_minimalpath = true;
    double minimalPath_alpha=0.1;
    double minimalPath_beta=1.0;
    double minimalPath_gamma=5.0;
    double minimalPath_sigmaMinimum=1.5;
    double minimalPath_sigmaMaximum=4.5;
    unsigned int minimalPath_numberOfSigmaSteps=10;
    double minimalPath_sigmaDistance=30.0;

    // Reading option parameters from user input
    cout << argc;
    for (int i = 0; i < argc; ++i) {
        if (strcmp(argv[i],"-i")==0) {
            i++;
            inputFilename = argv[i];
        }
        else if (strcmp(argv[i],"-i-dicom")==0) {
            i++;
            //inputFilename = argv[i];
            //input_dicom = true;
        }
        else if (strcmp(argv[i],"-o")==0) {
            i++;
            outputPath = argv[i];
        }
        else if (strcmp(argv[i],"-t")==0) {
            i++;
            if (strcmp(argv[i],"t1")==0) {
                typeImageFactor = -1.0;
                if (verbose) cout << endl << "WARNING: be sure your image is a T1-weighted image." << endl << endl;
            }
            else if (strcmp(argv[i],"t2")==0) {
                typeImageFactor = 1.0;
                if (verbose) cout << endl << "WARNING: be sure your image is a T2-weighted image." << endl << endl;
            }
            else {
                cout << "Error: Invalid type or image (need to be \"t1\" or \"t2\")" << endl << endl;
                help();
                return EXIT_FAILURE;
            }
        }
        else if (strcmp(argv[i],"-param-init")==0)
        {
            printf("\nPARAM INIT\n");
            // param structure delimited by commas:
            // minimalPath_alpha,minimalPath_beta,minimalPath_gamma,minimalPath_sigmaMinimum,minimalPath_sigmaMaximum,minimalPath_numberOfSigmaSteps,minimalPath_sigmaDistance
            vector<string> param_init = split(argv[i], ',');
            minimalPath_alpha = atof(param_init[0].c_str());
            printf("%f\n", minimalPath_alpha);
            minimalPath_beta = atof(param_init[1].c_str());
            printf("%f\n", minimalPath_beta);
            minimalPath_gamma = atof(param_init[2].c_str());
            printf("%f\n", minimalPath_gamma);
            minimalPath_sigmaMinimum = atof(param_init[3].c_str());
            printf("%f\n", minimalPath_sigmaMinimum);
            minimalPath_sigmaMaximum = atof(param_init[4].c_str());
            printf("%f\n", minimalPath_sigmaMaximum);
            minimalPath_numberOfSigmaSteps = atoi(param_init[5].c_str());
            printf("%i\n", minimalPath_numberOfSigmaSteps);
            minimalPath_sigmaDistance = atof(param_init[6].c_str());
            printf("%f\n", minimalPath_sigmaDistance);
        }
        else if (strcmp(argv[i],"-verbose")==0) {
            verbose = true;
        }
        else if (strcmp(argv[i],"-help")==0) {
            help();
            return EXIT_FAILURE;
        }
    }

    // Checking if user added mandatory arguments
    if (inputFilename == "")
    {
        cerr << "Input filename not provided" << endl;
        help();
        return EXIT_FAILURE;
    }
    if (typeImageFactor == 0)
    {
        cerr << "Error: The type of contrast not provided (option -t)" << endl;
        help();
        return EXIT_FAILURE;
    }

    // output files must have the same extension as input file
    string nii=".nii", niigz=".nii.gz";
    suffix=niigz;
    size_t pos = inputFilename.find(niigz);
    if (pos == string::npos) {
        pos = inputFilename.find(nii);
        suffix = nii;
    }

    // Extract the input file name
    unsigned found_slash = inputFilename.find_last_of("/\\");
    string inputFilename_nameonly = inputFilename.substr(found_slash+1);
    unsigned found_point = inputFilename_nameonly.find_first_of(".");
    inputFilename_nameonly = inputFilename_nameonly.substr(0,found_point);

    // Check if output folder ends with /
    if (outputPath!="" && outputPath.compare(outputPath.length()-1,1,"/")) outputPath += "/"; // add "/" if missing

    // Set output filenames
    outputFilenameBinary = outputPath+inputFilename_nameonly+"_seg"+suffix;
    outputFilenameMesh = outputPath+inputFilename_nameonly+"_mesh.vtk";
    outputFilenameBinaryCSF = outputPath+inputFilename_nameonly+"_CSF_seg"+suffix;
    outputFilenameMeshCSF = outputPath+inputFilename_nameonly+"_CSF_mesh.vtk";
    outputFilenameAreas = outputPath+inputFilename_nameonly+"_cross_sectional_areas.txt";
    outputFilenameAreasCSF = outputPath+inputFilename_nameonly+"_cross_sectional_areas_CSF.txt";
    outputFilenameCenterline = outputPath+inputFilename_nameonly+"_centerline.txt";
    outputFilenameCenterlineBinary = outputPath+inputFilename_nameonly+"_centerline"+suffix;
    // if output path doesn't exist, we create it
    if (outputPath!="") itk::FileTools::CreateDirectory(outputPath.c_str());

    // Image reading - image can be T1 or T2 (or Tx-like) depending on contrast between spinal cord and CSF
    // typeImageFactor depend of contrast type and is equal to +1 when CSF is brighter than spinal cord and equal to -1 inversely
    ImageType::Pointer initialImage, image = ImageType::New();

    ReaderType::Pointer reader = ReaderType::New();
    itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
    reader->SetImageIO(io);
    reader->SetFileName(inputFilename);
    try {
        reader->Update();
    } catch( itk::ExceptionObject & e ) {
        cerr << "ERROR: Exception caught while reading input image (-i option). Are you sure the image exist?" << endl;
        cerr << e << endl;
        return EXIT_FAILURE;
    }
    initialImage = reader->GetOutput();

    ImageType::SizeType desiredSize = initialImage->GetLargestPossibleRegion().GetSize();
    ImageType::SpacingType spacingI = initialImage->GetSpacing();

    // Intensity normalization
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
    rescaleFilter->SetInput(initialImage);
    rescaleFilter->SetOutputMinimum(0);
    rescaleFilter->SetOutputMaximum(1000);
    try {
        rescaleFilter->Update();
    } catch( itk::ExceptionObject & e ) {
        cerr << "Exception caught while normalizing input image " << endl;
        cerr << e << endl;
        return EXIT_FAILURE;
    }
    image = rescaleFilter->GetOutput();

    vesselnessFilter(image, typeImageFactor, minimalPath_alpha, minimalPath_beta, minimalPath_gamma, minimalPath_sigmaMinimum, minimalPath_sigmaMaximum, minimalPath_numberOfSigmaSteps, minimalPath_sigmaDistance);

    return EXIT_SUCCESS;
}