Exemple #1
0
int main(int argc, char* argv[]) {
    CSimpleOpt::SOption specs[] = {
        { 0, "-o", SO_REQ_SEP },
        SO_END_OF_OPTIONS
    };

    Options argParser;
    StringVector args = argParser.ParseOptions(argc, argv, specs);

    if (args.size() < 1) {
        cout << argv[0] << " [input-vector] [output-rgb]" << endl;
        return 1;
    }

    ImageIO<DeformFieldImageType> io;
    DeformFieldImageType::Pointer img = io.ReadImage(args[0]);

//    itk::UnaryFunctorImageFilter<DeformFieldImageType,RGBImageType> CastFilter;
    typedef itk::UnaryFunctorImageFilter<DeformFieldImageType, RGBImageType, Vector2RGB> CastFilter;
    CastFilter::Pointer caster = CastFilter::New();
    caster->SetInput(img);
    caster->Update();
    RGBImageType::Pointer rgbImg = caster->GetOutput();

    rgbImg->Print(cout);
    io.WriteImageS<RGBImageType>(args[1], rgbImg);

    return 0;
}
int main(int argc, char**argv)
{
	typedef itk::GradientAnisotropicDiffusionImageFilter<FloatImageType, FloatImageType> FilterType;

	if(!file_exists(argv[3]))
	{
		InputImageType::Pointer im = readImage<InputImageType>(argv[1]);

		typedef itk::CastImageFilter<InputImageType,FloatImageType> CastFilter;
		typedef itk::CastImageFilter<FloatImageType,InputImageType> ReverseCastFilter;
		FilterType::Pointer filter = FilterType::New();


		CastFilter::Pointer cfilter = CastFilter::New();
		cfilter->SetInput(im);
		filter->SetInput(cfilter->GetOutput());

		int num_i;
		float time_step;
		float conductance;
		sscanf(argv[2],"%d,%f,%f",&num_i,&time_step,&conductance);
		printf("time_step %f num_i %d conductance %f\n",time_step,num_i,conductance);
		filter->SetTimeStep(time_step);
		filter->SetNumberOfIterations(num_i);
		filter->SetConductanceParameter(conductance);
		filter->Update();

		FloatImageType::Pointer imf = filter->GetOutput();
		typedef itk::ImageRegionIterator<FloatImageType> IRI;
		IRI imageIterator(imf,imf->GetLargestPossibleRegion());
		for(imageIterator.GoToBegin();!imageIterator.IsAtEnd(); ++imageIterator)
		{
			float value = imageIterator.Get();
			value = ((value < 0)?0:((value>255)?255:value));
			imageIterator.Set(value);
		}

		ReverseCastFilter::Pointer rfilter = ReverseCastFilter::New();
		rfilter->SetInput(filter->GetOutput());
		rfilter->Update();
		writeImage<InputImageType>(rfilter->GetOutput(),argv[3]);
	}

	return 0;
}
//#################### PUBLIC METHODS ####################
void CTIPFBuilder::execute()
{
	typedef itk::Image<short,3> GradientMagnitudeImage;
	typedef itk::Image<int,3> HounsfieldImage;
	typedef itk::Image<float,3> RealImage;
	typedef itk::Image<unsigned char,3> WindowedImage;

	HounsfieldImage::Pointer hounsfieldImage = (*m_volume)->base_image();

	//~~~~~~~
	// STEP 1
	//~~~~~~~

	set_status("Preprocessing image...");

	// Construct the windowed image.
	WindowedImage::Pointer windowedImage = (*m_volume)->windowed_image(m_segmentationOptions.windowSettings);
	if(is_aborted()) return;

	// Cast the input image (whether Hounsfield or windowed) to make its pixels real-valued.
	RealImage::Pointer realImage;
	switch(m_segmentationOptions.inputType)
	{
		case CTSegmentationOptions::INPUTTYPE_HOUNSFIELD:
		{
			typedef itk::CastImageFilter<HounsfieldImage,RealImage> CastFilter;
			CastFilter::Pointer castFilter = CastFilter::New();
			castFilter->SetInput(hounsfieldImage);
			castFilter->Update();
			realImage = castFilter->GetOutput();
			break;
		}
		case CTSegmentationOptions::INPUTTYPE_WINDOWED:
		{
			typedef itk::CastImageFilter<WindowedImage,RealImage> CastFilter;
			CastFilter::Pointer castFilter = CastFilter::New();
			castFilter->SetInput(windowedImage);
			castFilter->Update();
			realImage = castFilter->GetOutput();
			break;
		}
		default:
		{
			throw Exception("Unknown CT segmentation input type");	// this should never happen
		}
	}
	if(is_aborted()) return;

	// Smooth this real image using anisotropic diffusion filtering.
	typedef itk::GradientAnisotropicDiffusionImageFilter<RealImage,RealImage> ADFilter;
	for(int i=0; i<m_segmentationOptions.adfIterations; ++i)
	{
		ADFilter::Pointer adFilter = ADFilter::New();
		adFilter->SetInput(realImage);
		adFilter->SetConductanceParameter(1.0);
		adFilter->SetNumberOfIterations(1);
		adFilter->SetTimeStep(0.0625);
		adFilter->Update();
		realImage = adFilter->GetOutput();

		if(is_aborted()) return;
		increment_progress();
	}

	// Calculate the gradient magnitude of the smoothed image.
	typedef itk::GradientMagnitudeImageFilter<RealImage,GradientMagnitudeImage> GMFilter;
	GMFilter::Pointer gmFilter = GMFilter::New();
	gmFilter->SetInput(realImage);
	gmFilter->SetUseImageSpacingOff();
	gmFilter->Update();
	GradientMagnitudeImage::Pointer gradientMagnitudeImage = gmFilter->GetOutput();

	if(is_aborted()) return;
	increment_progress();

	//~~~~~~~
	// STEP 2
	//~~~~~~~

	set_status("Running watershed...");

	// Run the watershed algorithm on the gradient magnitude image.
	typedef MeijsterRoerdinkWatershed<GradientMagnitudeImage::PixelType,3> WS;
	WS ws(gradientMagnitudeImage, ITKImageUtil::make_6_connected_offsets());

	if(is_aborted()) return;
	increment_progress();

	//~~~~~~~
	// STEP 3
	//~~~~~~~

	set_status("Creating initial partition forest...");
	boost::shared_ptr<CTImageLeafLayer> leafLayer(new CTImageLeafLayer(hounsfieldImage, windowedImage, gradientMagnitudeImage));
	if(is_aborted()) return;
	boost::shared_ptr<CTImageBranchLayer> lowestBranchLayer = IPF::make_lowest_branch_layer(leafLayer, ws.calculate_groups());
	if(is_aborted()) return;
	m_ipf.reset(new IPF(leafLayer, lowestBranchLayer));
	increment_progress();

	//~~~~~~~
	// STEP 4
	//~~~~~~~

	set_status("Creating rooted MST for lowest branch layer...");
	RootedMST<int> mst(*lowestBranchLayer);
	if(is_aborted()) return;
	increment_progress();

	//~~~~~~~
	// STEP 5
	//~~~~~~~

	set_status("Running waterfall...");

	// Iteratively run a Nicholls waterfall pass on the MST until the forest is built.
	typedef WaterfallPass<int>::Listener WaterfallPassListener;
	NichollsWaterfallPass<int> waterfallPass;
	boost::shared_ptr<WaterfallPassListener> listener = make_forest_building_waterfall_pass_listener(m_ipf);
	waterfallPass.add_listener(listener);
	while(mst.node_count() != 1 && m_ipf->highest_layer() < m_segmentationOptions.waterfallLayerLimit)
	{
		m_ipf->clone_layer(m_ipf->highest_layer());
		if(is_aborted()) return;
		waterfallPass.run(mst);
		if(is_aborted()) return;
	}

	set_finished();
}
Exemple #4
0
void forest_test()
{
	// Create the Hounsfield and 'windowed' images.
	typedef itk::Image<int,2> HounsfieldImage;
	typedef itk::Image<unsigned char,2> WindowedImage;
	typedef itk::Image<short,2> GradientMagnitudeImage;

	int pixels[] =
	{
		2,2,2,9,9,3,3,3,
		2,2,2,9,9,3,3,3,
		2,2,2,9,9,3,3,3,
		9,9,9,9,9,9,9,9,
		9,9,9,9,9,9,9,9,
		5,5,5,9,9,3,3,3,
		5,5,5,9,9,3,3,3,
		5,5,5,9,9,3,3,3,
	};

	HounsfieldImage::Pointer hounsfieldImage = ITKImageUtil::make_filled_image(8, 8, pixels);
	ITKImageUtil::output_image(std::cout, hounsfieldImage);
	std::cout << '\n';

	// This is not the proper way to do windowing - it's a hack for testing purposes.
	typedef itk::CastImageFilter<HounsfieldImage,WindowedImage> CastFilter;
	CastFilter::Pointer castFilter = CastFilter::New();
	castFilter->SetInput(hounsfieldImage);
	castFilter->Update();
	WindowedImage::Pointer windowedImage = castFilter->GetOutput();

	// Calculate the gradient magnitude image.
	typedef itk::GradientMagnitudeImageFilter<WindowedImage,GradientMagnitudeImage> GradientMagnitudeFilter;
	GradientMagnitudeFilter::Pointer gradientMagnitudeFilter = GradientMagnitudeFilter::New();
	gradientMagnitudeFilter->SetInput(windowedImage);
	gradientMagnitudeFilter->SetUseImageSpacingOff();
	gradientMagnitudeFilter->Update();

	GradientMagnitudeImage::Pointer gradientMagnitudeImage = gradientMagnitudeFilter->GetOutput();
	ITKImageUtil::output_image(std::cout, gradientMagnitudeImage);
	std::cout << '\n';

	// Run the watershed algorithm on the gradient magnitude image.
	typedef MeijsterRoerdinkWatershed<GradientMagnitudeImage::PixelType,2> WS;
	WS ws(gradientMagnitudeImage, ITKImageUtil::make_4_connected_offsets());

	// Output the results.
	ITKImageUtil::output_image(std::cout, ws.lower_complete());
	std::cout << '\n';

	ITKImageUtil::output_image(std::cout, ws.arrows());
	std::cout << '\n';

	ITKImageUtil::output_image(std::cout, ws.labels());
	std::cout << '\n';

	// Create the initial partition forest.
	typedef PartitionForest<CTImageLeafLayer,CTImageBranchLayer> IPF;
	typedef shared_ptr<IPF> IPF_Ptr;
	shared_ptr<CTImageLeafLayer> leafLayer(new CTImageLeafLayer(hounsfieldImage, windowedImage, gradientMagnitudeImage));
	shared_ptr<CTImageBranchLayer> lowestBranchLayer = IPF::make_lowest_branch_layer(leafLayer, ws.calculate_groups());
	std::copy(lowestBranchLayer->edges_cbegin(), lowestBranchLayer->edges_cend(), std::ostream_iterator<WeightedEdge<int> >(std::cout, " "));
	std::cout << '\n';
	IPF_Ptr ipf(new IPF(leafLayer, lowestBranchLayer));
}
//#################### PUBLIC METHODS ####################
void CTLowestLayersBuilder::execute()
{
	typedef itk::Image<short,3> GradientMagnitudeImage;
	typedef itk::Image<int,3> HounsfieldImage;
	typedef itk::Image<float,3> RealImage;
	typedef itk::Image<unsigned char,3> WindowedImage;

	HounsfieldImage::Pointer hounsfieldImage = (*m_volume)->base_image();

	//~~~~~~~
	// STEP 1
	//~~~~~~~

	set_status("Preprocessing image...");

	// Construct the windowed image.
	WindowedImage::Pointer windowedImage = (*m_volume)->windowed_image(m_segmentationOptions.windowSettings);
	if(is_aborted()) return;

	// Cast the input image (whether Hounsfield or windowed) to make its pixels real-valued.
	RealImage::Pointer realImage;
	switch(m_segmentationOptions.inputType)
	{
		case CTSegmentationOptions::INPUTTYPE_HOUNSFIELD:
		{
			typedef itk::CastImageFilter<HounsfieldImage,RealImage> CastFilter;
			CastFilter::Pointer castFilter = CastFilter::New();
			castFilter->SetInput(hounsfieldImage);
			castFilter->Update();
			realImage = castFilter->GetOutput();
			break;
		}
		case CTSegmentationOptions::INPUTTYPE_WINDOWED:
		{
			typedef itk::CastImageFilter<WindowedImage,RealImage> CastFilter;
			CastFilter::Pointer castFilter = CastFilter::New();
			castFilter->SetInput(windowedImage);
			castFilter->Update();
			realImage = castFilter->GetOutput();
			break;
		}
		default:
		{
			throw Exception("Unknown CT segmentation input type");	// this should never happen
		}
	}
	if(is_aborted()) return;

	// Smooth this real image using anisotropic diffusion filtering.
	typedef itk::GradientAnisotropicDiffusionImageFilter<RealImage,RealImage> ADFilter;
	for(int i=0; i<m_segmentationOptions.adfIterations; ++i)
	{
		ADFilter::Pointer adFilter = ADFilter::New();
		adFilter->SetInput(realImage);
		adFilter->SetConductanceParameter(1.0);
		adFilter->SetNumberOfIterations(1);
		adFilter->SetTimeStep(0.0625);
		adFilter->Update();
		realImage = adFilter->GetOutput();

		if(is_aborted()) return;
		increment_progress();
	}

	// Calculate the gradient magnitude of the smoothed image.
	typedef itk::GradientMagnitudeImageFilter<RealImage,GradientMagnitudeImage> GMFilter;
	GMFilter::Pointer gmFilter = GMFilter::New();
	gmFilter->SetInput(realImage);
	gmFilter->SetUseImageSpacingOff();
	gmFilter->Update();
	GradientMagnitudeImage::Pointer gradientMagnitudeImage = gmFilter->GetOutput();

	if(is_aborted()) return;
	increment_progress();

	//~~~~~~~
	// STEP 2
	//~~~~~~~

	set_status("Running watershed...");

	// Run the watershed algorithm on the gradient magnitude image.
	typedef MeijsterRoerdinkWatershed<GradientMagnitudeImage::PixelType,3> WS;
	WS ws(gradientMagnitudeImage, ITKImageUtil::make_6_connected_offsets());

	if(is_aborted()) return;
	increment_progress();

	//~~~~~~~
	// STEP 3
	//~~~~~~~

	set_status("Creating lowest forest layers...");

	m_leafLayer.reset(new CTImageLeafLayer(hounsfieldImage, windowedImage, gradientMagnitudeImage));
	if(is_aborted()) return;
	m_lowestBranchLayer = IPF::make_lowest_branch_layer(m_leafLayer, ws.calculate_groups());
	
	if(is_aborted()) return;
	set_finished();
}