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"); }
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(); }
// 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; } }
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 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(); }
/** * @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; }
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; }
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; }
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; }
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(); }
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()); } }
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; }
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; }