Exemplo n.º 1
0
void segmentation::on_filterButton_clicked()
{
    typedef    float    InputPixelType;
    typedef    float    OutputPixelType;
    typedef itk::Image< InputPixelType,  3 >   InputImageType;
    typedef itk::Image< OutputPixelType, 3>   OutputImageType;
    typedef itk::ImageFileReader< InputImageType >  ReaderType;
    typedef itk::CurvatureAnisotropicDiffusionImageFilter<
        InputImageType, OutputImageType >  FilterType;
    FilterType::Pointer filter = FilterType::New();
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName( inputFileName);
    filter->SetInput( reader->GetOutput() );
    const unsigned int numberOfIterations = 3;//5
    const double       timeStep =  0.0625; //timeStep=0.125(for 2D), 0.0625(for 3D)
    const double       conductance = 3;//3
    filter->SetNumberOfIterations( numberOfIterations );
    filter->SetTimeStep( timeStep );
    filter->SetConductanceParameter( conductance );
    filter->Update();//time-costing
    typedef unsigned short                        WritePixelType;//unsigned char
    typedef itk::Image< WritePixelType, 3 >        WriteImageType;
    typedef itk::RescaleIntensityImageFilter<
        OutputImageType, WriteImageType > RescaleFilterType;
    RescaleFilterType::Pointer rescaler = RescaleFilterType::New();
    rescaler->SetOutputMinimum(   0 );
    rescaler->SetOutputMaximum( 65535 );//255 for CNV,  for PED
    typedef itk::ImageFileWriter< WriteImageType >  WriterType;
    WriterType::Pointer writer = WriterType::New();
    //文件前缀名
    filePrefix = inputFileName;//char* to string
    filePrefix = filePrefix.substr(0, filePrefix.length() - 4);
    filePrefix = filePrefix + "_filter.mhd";
    strcpy(outputFileName, filePrefix.c_str());//string to char*
    writer->SetFileName(outputFileName);
    rescaler->SetInput( filter->GetOutput() );
    writer->SetInput( rescaler->GetOutput() );
    writer->Update();

    //将结果图返回主窗口显示
    emit returnOutputFileName(outputFileName);//发出信号
}
void CriminisiInpainting::InitializeConfidence()
{

  // Clone the mask - we need to invert the mask to actually perform the masking, but we don't want to disturb the original mask
  Mask::Pointer maskClone = Mask::New();
  //Helpers::DeepCopy<Mask>(this->CurrentMask, maskClone);
  maskClone->DeepCopyFrom(this->CurrentMask);
  
  // Invert the mask
  typedef itk::InvertIntensityImageFilter <Mask> InvertIntensityImageFilterType;

  InvertIntensityImageFilterType::Pointer invertIntensityFilter = InvertIntensityImageFilterType::New();
  invertIntensityFilter->SetInput(maskClone);
  //invertIntensityFilter->InPlaceOn();
  invertIntensityFilter->Update();

  // Convert the inverted mask to floats and scale them to between 0 and 1
  // to serve as the initial confidence image
  typedef itk::RescaleIntensityImageFilter< Mask, FloatScalarImageType > RescaleFilterType;
  RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
  rescaleFilter->SetInput(invertIntensityFilter->GetOutput());
  rescaleFilter->SetOutputMinimum(0);
  rescaleFilter->SetOutputMaximum(1);
  rescaleFilter->Update();

  Helpers::DeepCopy<FloatScalarImageType>(rescaleFilter->GetOutput(), this->ConfidenceImage);
  //WriteImage<FloatImageType>(this->ConfidenceImage, "InitialConfidence.mhd");
}
Exemplo n.º 3
0
ImageType::Pointer SBFilterUtils::RescaleImage(ImageType::Pointer image, int outputMin, int outputMax)
{
	RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
	rescaleFilter->SetInput(image);
	rescaleFilter->SetOutputMinimum(outputMin);
	rescaleFilter->SetOutputMaximum(outputMax);
	rescaleFilter->Update();
	
	return rescaleFilter->GetOutput();
}
Exemplo n.º 4
0
void Preprocess::RescaleIntensities(int min, int max)
{
	//Rescale the pixel values
    typedef itk::RescaleIntensityImageFilter< ImageType3D, ImageType3D > RescaleFilterType;
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
    rescaleFilter->SetInput( myImg );
	rescaleFilter->InPlaceOn();
	rescaleFilter->SetOutputMinimum( min );
    rescaleFilter->SetOutputMaximum( max );

	try
	{
		rescaleFilter->Update();
	}
	catch( itk::ExceptionObject & err )
	{
		std::cerr << "ITK FILTER ERROR: " << err << std::endl ;
	}

	myImg = rescaleFilter->GetOutput();
}
Exemplo n.º 5
0
// Convert a vector ITK image to a VTK image for display
void ITKImagetoVTKMagnitudeImage(FloatVectorImageType::Pointer image, vtkImageData* outputImage)
{
  std::cout << "ITKImagetoVTKMagnitudeImage()" << std::endl;
  // Compute the magnitude of the ITK image
  typedef itk::VectorMagnitudeImageFilter<
                  FloatVectorImageType, FloatScalarImageType >  VectorMagnitudeFilterType;

  // Create and setup a magnitude filter
  VectorMagnitudeFilterType::Pointer magnitudeFilter = VectorMagnitudeFilterType::New();
  magnitudeFilter->SetInput( image );
  magnitudeFilter->Update();

  // Rescale and cast for display
  typedef itk::RescaleIntensityImageFilter<
                  FloatScalarImageType, UnsignedCharScalarImageType > RescaleFilterType;

  RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
  rescaleFilter->SetOutputMinimum(0);
  rescaleFilter->SetOutputMaximum(255);
  rescaleFilter->SetInput( magnitudeFilter->GetOutput() );
  rescaleFilter->Update();

  // Setup and allocate the VTK image
  outputImage->SetNumberOfScalarComponents(1);
  outputImage->SetScalarTypeToUnsignedChar();
  outputImage->SetDimensions(image->GetLargestPossibleRegion().GetSize()[0],
                             image->GetLargestPossibleRegion().GetSize()[1],
                             1);

  outputImage->AllocateScalars();

  // Copy all of the scaled magnitudes to the output image
  itk::ImageRegionConstIteratorWithIndex<UnsignedCharScalarImageType> imageIterator(rescaleFilter->GetOutput(), rescaleFilter->GetOutput()->GetLargestPossibleRegion());
  imageIterator.GoToBegin();

  while(!imageIterator.IsAtEnd())
    {
    unsigned char* pixel = static_cast<unsigned char*>(outputImage->GetScalarPointer(imageIterator.GetIndex()[0],
                                                                                     imageIterator.GetIndex()[1],0));
    pixel[0] = imageIterator.Get();

    ++imageIterator;
    }
}
bool VolumeProcess::RescaleIntensities(int min, int max)
{
	//Rescale the pixel values,//by xiao liang
    typedef itk::RescaleIntensityImageFilter<ImageType, ImageType>  RescaleFilterType;
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
    rescaleFilter->SetInput( m_outputImage );
	rescaleFilter->InPlaceOn();
	rescaleFilter->SetOutputMinimum( min );
    rescaleFilter->SetOutputMaximum( max );
	try
	{
		rescaleFilter->Update();
	}
	catch( itk::ExceptionObject & err )
	{
		std::cerr << "ITK FILTER ERROR: " << err << std::endl ;
		return false;
	}
	m_outputImage = rescaleFilter->GetOutput();
	if(debug)
		std::cerr << "Rescale Filter Done" << std::endl;
	return true;
}
Exemplo n.º 7
0
  /**
   * @brief ConvertToRGBImage converts a gray image to RGB by filling all three channels with the gray intensity
   * @param grayImage
   * @return
   */
  mitk::Image::Pointer ConvertToRGBImage(mitk::Image::Pointer grayImage)
  {
    mitk::Image::Pointer rgbImage = mitk::Image::New();
    unsigned int *dim = grayImage->GetDimensions();
    rgbImage->Initialize(mitk::MakePixelType<PixelType, RGBPixelType,3>(),3,dim);
    rgbImage->SetGeometry(grayImage->GetGeometry());

    itk::Image<InputPixelType,3>::Pointer itkGrayImage = itk::Image<InputPixelType,3>::New();
    mitk::CastToItkImage(grayImage, itkGrayImage);


    mitk::ImagePixelWriteAccessor<RGBPixelType,3> writeAcc(rgbImage);


    typedef itk::RescaleIntensityImageFilter< itk::Image<InputPixelType,3>, itk::Image<PixelType,3> > RescaleFilterType;
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
    rescaleFilter->SetInput(itkGrayImage);
    rescaleFilter->SetOutputMinimum(0);
    rescaleFilter->SetOutputMaximum(255*255);
    rescaleFilter->Update();

    itk::Index<3> idx;
    RGBPixelType value;

    // Fill rgb image with gray values
    for (idx[2] =0; (unsigned int)idx[2] < dim[2]; idx[2]++)
    {
      for (idx[1] =0; (unsigned int)idx[1] < dim[1]; idx[1]++)
      {
        for (idx[0] =0; (unsigned int)idx[0] < dim[0]; idx[0]++)
        {
          value.Fill(rescaleFilter->GetOutput()->GetPixel(idx));
          writeAcc.SetPixelByIndex(idx, value);
        }
      }
    }
    return rgbImage;
  }
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
int main(int argc, char *argv[])
{

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 } // end else

 free(GraphcutResults);
 GraphcutResults=NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

  //cout << "Done" << endl;
  return 0;
}
Exemplo n.º 10
0
int main(int argc, char *argv[])
{
	if (argc < 3)
	{
		std::cerr << "Usage: "
			<< "<input filename> "
			<< "<output filename> "
			<< std::endl;
		return 1;
	}
	
	typedef unsigned short InputPixelType;
	typedef unsigned char OutputPixelType;
	
	const unsigned Dimension = 3;

	typedef itk::Image<InputPixelType, Dimension> InputImageType;
	typedef itk::Image<OutputPixelType, Dimension> OutputImageType;

	typedef itk::ImageFileReader<InputImageType> InputReaderType;
	typedef itk::ImageFileWriter<OutputImageType> OutputWriterType;

	InputReaderType::Pointer reader = InputReaderType::New();
	OutputWriterType::Pointer writer = OutputWriterType::New();

	const char* outputFilename = argv[2];
	const char* inputFilename = argv[1];

	reader->SetFileName(inputFilename);
	try
	{
		reader->Update();
	}
	catch (itk::ExceptionObject &err)
	{
		std::cerr << "Error in reader: " << err << std::endl;
		return -1;
	}
	
	typedef itk::RescaleIntensityImageFilter<InputImageType, OutputImageType> RescaleFilterType;
	RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();

	rescaleFilter->SetInput(reader->GetOutput());
	rescaleFilter->SetOutputMinimum(0);
	rescaleFilter->SetOutputMaximum(255);
	
	try
	{
		rescaleFilter->Update();
	}
	catch (itk::ExceptionObject &err)
	{
		std::cerr << "Error in rescaleFilter: " << err << std::endl;
		return -1;
	}

	writer->SetInput(rescaleFilter->GetOutput());
	
	writer->SetFileName(outputFilename);
	
	try
	{
		writer->Update();
	}
	catch (itk::ExceptionObject &err)
	{
		std::cerr << "Error in writer: " << err << std::endl;
		return -1;
	}
	writer->Update();	
}
Exemplo n.º 11
0
void ImageFileManger::ProcessFiles()
{
	if (!this->InputFileList.isEmpty())
	{
		QDir directory(this->imageDir);
		for (int k = 0; k < this->outputDirectories.size(); k++)
		{
			directory.mkdir(this->outputDirectories[k]);
		}
		QProgressDialog progress("Converting Images", "Abort", 0, this->InputFileList.size(), this);
		progress.setWindowModality(Qt::WindowModal);
		for (int i = 0; i < this->InputFileList.size(); i++)
		{
			progress.setValue(i);
			if (progress.wasCanceled())
			{
				break;
			}
			QString currentDir;
			currentDir.clear();
			QString tempname = QFileInfo(this->InputFileList[i]).fileName();
			for (int j = 0; j < this->outputDirectories.size(); j++)
			{
				if (tempname.contains(this->outputDirectories.at(j), Qt::CaseInsensitive))
				{
					currentDir = this->outputDirectories.at(j);
				}//end search
			}
			if (currentDir.isEmpty())
			{
				continue;
			}
			tempname.replace(" ", "_");
			tempname.prepend("8Bit");
			QString outputFilename = QString(this->imageDir +"/"+ currentDir +"/"+tempname);

			InputReaderType::Pointer reader = InputReaderType::New();
			OutputWriterType::Pointer writer = OutputWriterType::New();
			reader->SetFileName(this->InputFileList[i].toStdString().c_str());

			//16 to 8 bit conversion
			RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
			rescaleFilter->SetInput(reader->GetOutput());
			rescaleFilter->SetOutputMinimum(0);
			rescaleFilter->SetOutputMaximum(255);
			rescaleFilter->Update();

			preprocessdialog->SetImage( rescaleFilter->GetOutput() );
			
			writer->SetFileName(outputFilename.toStdString().c_str());
			try
			{
				preprocessdialog->Process();
				writer->SetInput(preprocessdialog->GetImage());
				writer->Update();
			}
			catch(itk::ExceptionObject & e) 
			{
				std::cerr << "Exception in ITK Pipeline: " << e << std::endl;
				continue;
			}
		}
		progress.setValue(this->InputFileList.size());
	}
	
	
}
Exemplo n.º 12
0
int runGrAnisDiff(unsigned char* imgIn, int r, int c, int z, int iter, int timeStep, int comductance)
{
	
	//pixel types
	typedef unsigned char InputPixelType;
	typedef float OutputPixelType;
	typedef itk::Image< InputPixelType, 3 > InputImageType;
	typedef itk::Image< OutputPixelType, 3 > OutputImageType;
	
	//create an ITK image from the input image
	OutputImageType::Pointer im;
	im = OutputImageType::New();
	OutputImageType::PointType origin;
    origin[0] = 0.; 
    origin[1] = 0.;    
	origin[2] = 0.;    
    im->SetOrigin( origin );

    OutputImageType::IndexType start;
    start[0] =   0;  // first index on X
    start[1] =   0;  // first index on Y    
	start[2] =   0;  // first index on Z    
    OutputImageType::SizeType  size;
    size[0]  = c;  // size along X
    size[1]  = r;  // size along Y
	size[2]  = z;  // size along Z
  
    OutputImageType::RegionType region;
    region.SetSize( size );
    region.SetIndex( start );
    
 //   double spacing[3];
	//spacing[0] = 1; //spacing along x
	//spacing[1] = 1; //spacing along y
	//spacing[2] = sampl_ratio; //spacing along z

    im->SetRegions( region );
	//im->SetSpacing(spacing);
    im->Allocate();
    im->FillBuffer(0);
	im->Update();	
	
	//copy the input image into the ITK image
	typedef itk::ImageRegionIteratorWithIndex< OutputImageType > IteratorType;
	IteratorType iterator1(im,im->GetRequestedRegion());
	
	for(int i=0; i<r*c*z; i++)
	{					
		iterator1.Set((float)imgIn[i]);
		++iterator1;		
	}

	//apply gradient anisotropic diffusion
	typedef itk::GradientAnisotropicDiffusionImageFilter< OutputImageType, OutputImageType > FilterType;
	FilterType::Pointer filter = FilterType::New();
	filter->SetInput( im );

	filter->SetNumberOfIterations( iter );
	filter->SetTimeStep( timeStep );
	filter->SetConductanceParameter( comductance );

	try
	{
		filter->Update();
	}
	catch( itk::ExceptionObject & err ) 
    { 
		std::cerr << err << std::endl;
		return 0;
	}

	typedef itk::RescaleIntensityImageFilter< OutputImageType, InputImageType > RescaleFilterType;

	RescaleFilterType::Pointer rescaler = RescaleFilterType::New();
	rescaler->SetOutputMinimum(   0 );
	rescaler->SetOutputMaximum( 255 );
	rescaler->SetInput( filter->GetOutput() );
	rescaler->Update();

	//overwrite the input image for now in order to save space
	typedef itk::ImageRegionIteratorWithIndex< InputImageType > IteratorType2;
	IteratorType2 iterator2(rescaler->GetOutput(),rescaler->GetOutput()->GetRequestedRegion());
	
	for(int i=0; i<r*c*z; i++)
	{					
		imgIn[i] = iterator2.Get();
		++iterator2;		
	}

	return 1;
}
void Initialisation::savePointAsAxialImage(ImageType::Pointer initialImage, string filename)
{
    if (points_.size() > 0)
    {
        double radius = 2.0;
        //if (initialRadius_/stretchingFactor_ > radius_) radius = radius_*stretchingFactor_; // initialRadius_ majored by radius_
        //else radius = initialRadius_;
        typedef itk::ImageDuplicator< ImageType > DuplicatorType3D;
        DuplicatorType3D::Pointer duplicator = DuplicatorType3D::New();
        duplicator->SetInputImage(initialImage);
        duplicator->Update();
        ImageType::Pointer clonedImage = duplicator->GetOutput();
        
        // Intensity normalization
        RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
        rescaleFilter->SetInput(clonedImage);
        rescaleFilter->SetOutputMinimum(0);
        rescaleFilter->SetOutputMaximum(255);
        try {
            rescaleFilter->Update();
        } catch( itk::ExceptionObject & e ) {
            cerr << "Exception caught while normalizing input image " << endl;
            cerr << e << endl;
        }
        clonedImage = rescaleFilter->GetOutput();
        
        typedef itk::RGBPixel<unsigned char> RGBPixelType;
        typedef itk::Image<RGBPixelType, 2> RGBImageType;
		typedef itk::ExtractImageFilter< ImageType, RGBImageType > ExtractorTypeRGB;

		PointType pt; pt[0] = initialPoint_[0]; pt[1] = initialPoint_[1]; pt[2] = initialPoint_[2];
        ImageType::IndexType ind;
        clonedImage->TransformPhysicalPointToIndex(pt,ind);

		ImageType::SizeType desiredSize = clonedImage->GetLargestPossibleRegion().GetSize();
		ImageType::IndexType desiredStart;
		desiredStart[0] = 0; desiredStart[1] = ind[1]; desiredStart[2] = 0;
		desiredSize[1] = 0;
		ImageType::RegionType desiredRegion(desiredStart, desiredSize);
		ExtractorTypeRGB::Pointer filter = ExtractorTypeRGB::New();
		filter->SetExtractionRegion(desiredRegion);
		filter->SetInput(clonedImage);
		#if ITK_VERSION_MAJOR >= 4
		filter->SetDirectionCollapseToIdentity(); // This is required.
		#endif
		try {
			filter->Update();
		} catch( itk::ExceptionObject & e ) {
			std::cerr << "Exception caught while updating ExtractorTypeRGB " << std::endl;
			std::cerr << e << std::endl;
		}
		RGBImageType::Pointer image = filter->GetOutput();
        
		// draw cross
        RGBPixelType pixel; pixel[0] = 255; pixel[1] = 255; pixel[2] = 255;
		for (int x=-radius; x<=radius; x++) {
			RGBImageType::IndexType ind_x, ind_y;
			ind_x[0] = ind[0]+x; ind_x[1] = ind[2]; ind_y[0] = ind[0]; ind_y[1] = ind[2]+x;
			image->SetPixel(ind_x, pixel);
			image->SetPixel(ind_y, pixel);
		}

		typedef itk::ImageFileWriter< RGBImageType > WriterRGBType;
		itk::PNGImageIO::Pointer ioPNG = itk::PNGImageIO::New();
		WriterRGBType::Pointer writerPNG = WriterRGBType::New();
		writerPNG->SetInput(image);
		writerPNG->SetImageIO(ioPNG);
		writerPNG->SetFileName(filename);
		try {
		    writerPNG->Update();
		}
		catch( itk::ExceptionObject & e )
		{
			cout << "Exception thrown ! " << endl;
			cout << "An error ocurred during Writing PNG" << endl;
			cout << "Location    = " << e.GetLocation()    << endl;
			cout << "Description = " << e.GetDescription() << endl;
		}
    }
    else cout << "Error: Spinal cord center not detected" << endl;
}
Exemplo n.º 14
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;
}