コード例 #1
0
ファイル: ftkPreprocess2.cpp プロジェクト: Pandolph/farsight
void Preprocess::CannyEdgeDetection(float variance, float upperThreshold, float lowerThreshold)
{
	typedef itk::CastImageFilter< ImageType3D, FloatImageType3D > CastFilterType;
	CastFilterType::Pointer cast = CastFilterType::New();
	cast->SetInput( myImg );

	typedef itk::CannyEdgeDetectionImageFilter< FloatImageType3D, FloatImageType3D > FilterType;
	FilterType::Pointer filter = FilterType::New();
	filter->SetInput( cast->GetOutput() );
	filter->SetUpperThreshold(upperThreshold);		//Threshold for detected edges = threshold
	filter->SetLowerThreshold(lowerThreshold);		//Threshold for detected edges = threshold/2
	//filter->SetThreshold(threshold);		//Lowest allowed value in the output image
	filter->SetVariance(variance);			//For Gaussian smoothing
	//filter->SetMaximumError(.01f);		//For Gaussian smoothing

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

	myImg = RescaleFloatToImageType( filter->GetOutput() );
}
コード例 #2
0
//generate binary segment at actual CT image
BinaryImageTreeItem *CTImageTreeItem::generateSegment(void) {
	typedef itk::CastImageFilter< CTImageType, BinaryImageType> CastFilterType;
  
	bool ok;
	//show dialog for segment name
	QString segName = QInputDialog::getText(NULL, QObject::tr("Segment Name"),
						QObject::tr("Name:"), QLineEdit::Normal,
						QObject::tr("Unnamed Segment"), &ok);
	BinaryImageTreeItem::ImageType::Pointer seg;
	//if name is valid and dialog was closed with OK
	if (ok && !segName.isEmpty()) {
	    //create caster, that transforme the CT image to a binary image
		CastFilterType::Pointer caster = CastFilterType::New();
		caster->SetInput( getITKImage() );
		caster->Update();
		seg = caster->GetOutput();
		//fills the segment with zeros
		seg->FillBuffer(BinaryPixelOff);
		//create a binary tree item as child of this CT image
		BinaryImageTreeItem *result = new BinaryImageTreeItem(this, seg, segName);
		//insert child into the hierarchy
		insertChild(result);
		return result;
	}
	return NULL;
}
コード例 #3
0
int main (int argc, char *argv[])
{
  // Verify arguments
  if(argc != 3)
    {
    std::cerr << "Required arguments: InputFileName OutputFileName" << std::endl;
    return EXIT_FAILURE;
    }

  // Parse arguments
  std::string inputFileName = argv[1];
  std::string outputFileName = argv[2];

  // Output arguments
  std::cout << "Input image: " << inputFileName << std::endl;
  std::cout << "Output image: " << outputFileName << std::endl;
  
  //typedef itk::Image<unsigned char, 2> ImageType;
  
  typedef itk::RGBPixel<float> RGBFloatPixelType; // We must use float pixels so that the averaging operation does not overflow
  typedef itk::Image<RGBFloatPixelType> RGBFloatImageType;
  
  typedef itk::ImageFileReader<RGBFloatImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);
  reader->Update();
  
  SmallHoleFiller<RGBFloatImageType> smallHoleFiller;
  smallHoleFiller.SetImage(reader->GetOutput());
  
  RGBFloatImageType::PixelType green;
  green.SetRed(0);
  green.SetGreen(255);
  green.SetBlue(0);
  smallHoleFiller.SetHolePixel(green);

  smallHoleFiller.GenerateMaskFromImage();
  smallHoleFiller.Fill();
  
  typedef itk::RGBPixel<unsigned char> RGBUCharPixelType;
  typedef itk::Image<RGBUCharPixelType> RGBUCharImageType;
  typedef itk::CastImageFilter<RGBFloatImageType, RGBUCharImageType> CastFilterType;
  CastFilterType::Pointer castFilter = CastFilterType::New();
  castFilter->SetInput(smallHoleFiller.GetOutput());
  castFilter->Update();
  
  typedef  itk::ImageFileWriter< RGBUCharImageType  > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFileName);
  writer->SetInput(castFilter->GetOutput());
  writer->Update();
    
  return EXIT_SUCCESS;
}
コード例 #4
0
ImageType::Pointer SBFilterUtils::GaussianSmoothImage(ImageType::Pointer image, float variance) {
	
	GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
	gaussianFilter->SetInput(image);
	gaussianFilter->SetVariance(variance);
	gaussianFilter->Update();

	CastFilterType::Pointer castFilter = CastFilterType::New();
	castFilter->SetInput(gaussianFilter->GetOutput());
	castFilter->Update();

	return castFilter->GetOutput();
}
コード例 #5
0
//generate binary segment at actual CT image
BinaryImageTreeItem *CTImageTreeItem::generateSegment(QString name) {
	typedef itk::CastImageFilter< CTImageType, BinaryImageType> CastFilterType;
	
	BinaryImageTreeItem::ImageType::Pointer seg;
	//if name is valid and dialog was closed with OK
	if (!name.isEmpty()) {
	    //create caster, that transforme the CT image to a binary image
		CastFilterType::Pointer caster = CastFilterType::New();
		caster->SetInput( getITKImage() );
		caster->Update();
		seg = caster->GetOutput();
		//fills the segment with zeros
		seg->FillBuffer(BinaryPixelOff);
		//create a binary tree item as child of this CT image
		BinaryImageTreeItem *result = new BinaryImageTreeItem(this, seg, name);
		//insert child into the hierarchy
		insertChild(result);
		return result;
	}
	return NULL;
}
コード例 #6
0
int main( int argc, char *argv[] )
{
if( argc < 4 )
{
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0];
std::cerr << " fixedImageFile movingImageFile ";
std::cerr << " outputImagefile [differenceBeforeRegistration] ";
std::cerr << " [differenceAfterRegistration] ";
std::cerr << " [sliceBeforeRegistration] ";
std::cerr << " [sliceDifferenceBeforeRegistration] ";
std::cerr << " [sliceDifferenceAfterRegistration] ";
std::cerr << " [sliceAfterRegistration] " << std::endl;
return EXIT_FAILURE;
}
const unsigned int Dimension = 3;
typedef float PixelType;
typedef itk::Image< PixelType, Dimension > FixedImageType;
typedef itk::Image< PixelType, Dimension > MovingImageType;
// Software Guide : BeginLatex
//
// The Transform class is instantiated using the code below. The only
// template parameter to this class is the representation type of the
// space coordinates.
//
// \index{itk::Versor\-Rigid3D\-Transform!Instantiation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet

// Software Guide : EndCodeSnippet


typedef itk:: LinearInterpolateImageFunction< MovingImageType, double > InterpolatorType;
typedef itk::ImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType;

MetricType::Pointer metric = MetricType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
InterpolatorType::Pointer interpolator = InterpolatorType::New();
RegistrationType::Pointer registration = RegistrationType::New();
registration->SetMetric( metric );
registration->SetOptimizer( optimizer );
registration->SetInterpolator( interpolator );
// Software Guide : BeginLatex
//
// The transform object is constructed below and passed to the registration
// method.
//
// \index{itk::Versor\-Rigid3D\-Transform!New()}
// \index{itk::Versor\-Rigid3D\-Transform!Pointer}
// \index{itk::Registration\-Method!SetTransform()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
TransformType::Pointer transform = TransformType::New();
registration->SetTransform( transform );
// Software Guide : EndCodeSnippet
typedef itk::ImageFileReader< FixedImageType > FixedImageReaderType;
typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;
FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New();
MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New();
fixedImageReader->SetFileName( argv[1] );
movingImageReader->SetFileName( argv[2] );
registration->SetFixedImage( fixedImageReader->GetOutput() );
registration->SetMovingImage( movingImageReader->GetOutput() );
fixedImageReader->Update();
registration->SetFixedImageRegion(
fixedImageReader->GetOutput()->GetBufferedRegion() );
// Software Guide : BeginLatex
//
// The input images are taken from readers. It is not necessary here to
// explicitly call \code{Update()} on the readers since the
// \doxygen{CenteredTransformInitializer} will do it as part of its
// computations. The following code instantiates the type of the
// initializer. This class is templated over the fixed and moving image type
// as well as the transform type. An initializer is then constructed by
// calling the \code{New()} method and assigning the result to a smart
// pointer.
//
// \index{itk::Centered\-Transform\-Initializer!Instantiation}
// \index{itk::Centered\-Transform\-Initializer!New()}
// \index{itk::Centered\-Transform\-Initializer!SmartPointer}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : BeginLatex
//
// Let's execute this example over some of the images available in the ftp
// site
//
// \url{ftp://public.kitware.com/pub/itk/Data/BrainWeb}
//
// Note that the images in the ftp site are compressed in \code{.tgz} files.
// You should download these files an uncompress them in your local system.
// After decompressing and extracting the files you could take a pair of
// volumes, for example the pair:
//
// \begin{itemize}
// \item \code{brainweb1e1a10f20.mha}
// \item \code{brainweb1e1a10f20Rot10Tx15.mha}
// \end{itemize}
//
// The second image is the result of intentionally rotating the first image
// by $10$ degrees around the origin and shifting it $15mm$ in $X$. The
// registration takes $24$ iterations and produces:
//
// \begin{center}
// \begin{verbatim}
// [-6.03744e-05, 5.91487e-06, -0.0871932, 2.64659, -17.4637, -0.00232496]
// \end{verbatim}
// \end{center}
//
// That are interpreted as
//
// \begin{itemize}
// \item Versor = $(-6.03744e-05, 5.91487e-06, -0.0871932)$
// \item Translation = $(2.64659, -17.4637, -0.00232496)$ millimeters
// \end{itemize}
//
// This Versor is equivalent to a rotation of $9.98$ degrees around the $Z$
// axis.
//
// Note that the reported translation is not the translation of $(15.0,0.0,0.0)$
// that we may be naively expecting. The reason is that the
// \code{VersorRigid3DTransform} is applying the rotation around the center
// found by the \code{CenteredTransformInitializer} and then adding the
// translation vector shown above.
//
// It is more illustrative in this case to take a look at the actual
// rotation matrix and offset resulting form the $6$ parameters.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
transform->SetParameters( finalParameters );
TransformType::MatrixType matrix = transform->GetMatrix();
TransformType::OffsetType offset = transform->GetOffset();
std::cout << "Matrix = " << std::endl << matrix << std::endl;
std::cout << "Offset = " << std::endl << offset << std::endl;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The output of this print statements is
//
// \begin{center}
// \begin{verbatim}
// Matrix =
// 0.984795 0.173722 2.23132e-05
// -0.173722 0.984795 0.000119257
// -1.25621e-06 -0.00012132 1
//
// Offset =
// [-15.0105, -0.00672343, 0.0110854]
// \end{verbatim}
// \end{center}
//
// From the rotation matrix it is possible to deduce that the rotation is
// happening in the X,Y plane and that the angle is on the order of
// $\arcsin{(0.173722)}$ which is very close to 10 degrees, as we expected.
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
//
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceBorder20}
// \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceR10X13Y17}
// \itkcaption[CenteredTransformInitializer input images]{Fixed and moving image
// provided as input to the registration method using
// CenteredTransformInitializer.}
// \label{fig:FixedMovingImageRegistration8}
// \end{figure}
//
//
// \begin{figure}
// \center
// \includegraphics[width=0.32\textwidth]{ImageRegistration8Output}
// \includegraphics[width=0.32\textwidth]{ImageRegistration8DifferenceBefore}
// \includegraphics[width=0.32\textwidth]{ImageRegistration8DifferenceAfter}
// \itkcaption[CenteredTransformInitializer output images]{Resampled moving
// image (left). Differences between fixed and moving images, before (center)
// and after (right) registration with the
// CenteredTransformInitializer.}
// \label{fig:ImageRegistration8Outputs}
// \end{figure}
//
// Figure \ref{fig:ImageRegistration8Outputs} shows the output of the
// registration. The center image in this figure shows the differences
// between the fixed image and the resampled moving image before the
// registration. The image on the right side presents the difference between
// the fixed image and the resampled moving image after the registration has
// been performed. Note that these images are individual slices extracted
// from the actual volumes. For details, look at the source code of this
// example, where the ExtractImageFilter is used to extract a slice from the
// the center of each one of the volumes. One of the main purposes of this
// example is to illustrate that the toolkit can perform registration on
// images of any dimension. The only limitations are, as usual, the amount of
// memory available for the images and the amount of computation time that it
// will take to complete the optimization process.
//
// \begin{figure}
// \center
// \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceMetric}
// \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceAngle}
// \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceTranslations}
// \itkcaption[CenteredTransformInitializer output plots]{Plots of the metric,
// rotation angle, center of rotation and translations during the
// registration using CenteredTransformInitializer.}
// \label{fig:ImageRegistration8Plots}
// \end{figure}
//
// Figure \ref{fig:ImageRegistration8Plots} shows the plots of the main
// output parameters of the registration process. The metric values at every
// iteration. The Z component of the versor is plotted as an indication of
// how the rotation progress. The X,Y translation components of the
// registration are plotted at every iteration too.
//
// Shell and Gnuplot scripts for generating the diagrams in
// Figure~\ref{fig:ImageRegistration8Plots} are available in the directory
//
// \code{InsightDocuments/SoftwareGuide/Art}
//
// You are strongly encouraged to run the example code, since only in this
// way you can gain a first hand experience with the behavior of the
// registration process. Once again, this is a simple reflection of the
// philosophy that we put forward in this book:
//
// \emph{If you can not replicate it, then it does not exist!}.
//
// We have seen enough published papers with pretty pictures, presenting
// results that in practice are impossible to replicate. That is vanity, not
// science.
//
// Software Guide : EndLatex
typedef itk::ResampleImageFilter<
MovingImageType,
FixedImageType > ResampleFilterType;
TransformType::Pointer finalTransform = TransformType::New();
finalTransform->SetCenter( transform->GetCenter() );
finalTransform->SetParameters( finalParameters );
finalTransform->SetFixedParameters( transform->GetFixedParameters() );
ResampleFilterType::Pointer resampler = ResampleFilterType::New();
resampler->SetTransform( finalTransform );
resampler->SetInput( movingImageReader->GetOutput() );
FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
resampler->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
resampler->SetOutputOrigin( fixedImage->GetOrigin() );
resampler->SetOutputSpacing( fixedImage->GetSpacing() );
resampler->SetOutputDirection( fixedImage->GetDirection() );
resampler->SetDefaultPixelValue( 100 );
typedef unsigned char OutputPixelType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
typedef itk::CastImageFilter< FixedImageType, OutputImageType > CastFilterType;
typedef itk::ImageFileWriter< OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
CastFilterType::Pointer caster = CastFilterType::New();
writer->SetFileName( argv[3] );
caster->SetInput( resampler->GetOutput() );
writer->SetInput( caster->GetOutput() );
writer->Update();
typedef itk::SubtractImageFilter<
FixedImageType,
FixedImageType,
FixedImageType > DifferenceFilterType;
DifferenceFilterType::Pointer difference = DifferenceFilterType::New();
typedef itk::RescaleIntensityImageFilter<
FixedImageType,
OutputImageType > RescalerType;
RescalerType::Pointer intensityRescaler = RescalerType::New();
intensityRescaler->SetInput( difference->GetOutput() );
intensityRescaler->SetOutputMinimum( 0 );
intensityRescaler->SetOutputMaximum( 255 );
difference->SetInput1( fixedImageReader->GetOutput() );
difference->SetInput2( resampler->GetOutput() );
resampler->SetDefaultPixelValue( 1 );
WriterType::Pointer writer2 = WriterType::New();
writer2->SetInput( intensityRescaler->GetOutput() );
// Compute the difference image between the
// fixed and resampled moving image.
if( argc > 5 )
{
writer2->SetFileName( argv[5] );
writer2->Update();
}
typedef itk::IdentityTransform< double, Dimension > IdentityTransformType;
IdentityTransformType::Pointer identity = IdentityTransformType::New();
// Compute the difference image between the
// fixed and moving image before registration.
if( argc > 4 )
{
resampler->SetTransform( identity );
writer2->SetFileName( argv[4] );
writer2->Update();
}
//
// Here we extract slices from the input volume, and the difference volumes
// produced before and after the registration. These slices are presented as
// figures in the Software Guide.
//
//
typedef itk::Image< OutputPixelType, 2 > OutputSliceType;
typedef itk::ExtractImageFilter<
OutputImageType,
OutputSliceType > ExtractFilterType;
ExtractFilterType::Pointer extractor = ExtractFilterType::New();
extractor->SetDirectionCollapseToSubmatrix();
extractor->InPlaceOn();
FixedImageType::RegionType inputRegion =
fixedImage->GetLargestPossibleRegion();
FixedImageType::SizeType size = inputRegion.GetSize();
FixedImageType::IndexType start = inputRegion.GetIndex();
// Select one slice as output
size[2] = 0;
start[2] = 90;
FixedImageType::RegionType desiredRegion;
desiredRegion.SetSize( size );
desiredRegion.SetIndex( start );
extractor->SetExtractionRegion( desiredRegion );
typedef itk::ImageFileWriter< OutputSliceType > SliceWriterType;
SliceWriterType::Pointer sliceWriter = SliceWriterType::New();
sliceWriter->SetInput( extractor->GetOutput() );
if( argc > 6 )
{
extractor->SetInput( caster->GetOutput() );
resampler->SetTransform( identity );
sliceWriter->SetFileName( argv[6] );
sliceWriter->Update();
}
if( argc > 7 )
{
extractor->SetInput( intensityRescaler->GetOutput() );
resampler->SetTransform( identity );
sliceWriter->SetFileName( argv[7] );
sliceWriter->Update();
}
if( argc > 8 )
{
resampler->SetTransform( finalTransform );
sliceWriter->SetFileName( argv[8] );
sliceWriter->Update();
}
if( argc > 9 )
{
extractor->SetInput( caster->GetOutput() );
resampler->SetTransform( finalTransform );
sliceWriter->SetFileName( argv[9] );
sliceWriter->Update();
}
return EXIT_SUCCESS;
}
コード例 #7
0
double Mesh::computeStandardDeviationFromPixelsInside(ImageType::Pointer image)
{
    MeshTypeB::Pointer mesh = MeshTypeB::New();
    typedef itk::Point< double, 3 > PointType;
    PointType pnt;
    ImageType::IndexType index;
    CVector3 p, n, min(10000,10000,10000), max;
    for (unsigned int i=0; i<points_.size(); i++) {
        p = points_[i]->getPosition();
        pnt[0] = p[0]; pnt[1] = p[1]; pnt[2] = p[2];
        mesh->SetPoint(i,pnt);
        
        image->TransformPhysicalPointToIndex(pnt, index);
        if (index[0]<min[0]) min[0]=index[0];
        if (index[1]<min[1]) min[1]=index[1];
        if (index[2]<min[2]) min[2]=index[2];
        if (index[0]>max[0]) max[0]=index[0];
        if (index[1]>max[1]) max[1]=index[1];
        if (index[2]>max[2]) max[2]=index[2];
    }
    for (unsigned int i=0; i<triangles_.size(); i+=3)
    {
        CellTypeB::CellAutoPointer triangle;
        triangle.TakeOwnership(new CellTypeB);
        triangle->SetPointId(0,triangles_[i]);
        triangle->SetPointId(1,triangles_[i+1]);
        triangle->SetPointId(2,triangles_[i+2]);
        mesh->SetCell((int)(i+1)/3,triangle);
    }
    
    
    CastFilterType::Pointer castFilter = CastFilterType::New();
    castFilter->SetInput(image);
    BinaryImageType::Pointer im = castFilter->GetOutput();
    
    BinaryImageType::IndexType indexRegion;
    BinaryImageType::SizeType sizeRegion;
    sizeRegion[0] = max[0]-min[0]+5; // adding two pixels at each side to be sure
    sizeRegion[1] = max[1]-min[1]+5;
    sizeRegion[2] = max[2]-min[2]+5;
    indexRegion[0] = min[0]-2;
    indexRegion[1] = min[1]-2;
    indexRegion[2] = min[2]-2;
    
    BinaryImageType::RegionType region(indexRegion,sizeRegion);
    im->SetRegions(region);
    
    MeshFilterType::Pointer meshFilter = MeshFilterType::New();
    meshFilter->SetInput(mesh);
    meshFilter->SetInfoImage(im);
    /*meshFilter->SetDirection(image->GetDirection());
    meshFilter->SetSpacing(image->GetSpacing());
    meshFilter->SetOrigin(image->GetOrigin());
    meshFilter->SetSize(sizeRegion);
    meshFilter->SetIndex(indexRegion);*/
    meshFilter->SetTolerance(1.0);
    meshFilter->SetInsideValue(1.0);
    meshFilter->SetOutsideValue(0.0);
    try {
        meshFilter->Update();
    }
    catch( itk::ExceptionObject & e )
    {
        cout << "Exception thrown ! " << endl;
        cout << "An error ocurred during creating binary image" << endl;
        cout << "Location    = " << e.GetLocation()    << endl;
        cout << "Description = " << e.GetDescription() << endl;
    }
    
    MeshFilterType::OutputImageType::Pointer binary = meshFilter->GetOutput();
    
    vector<double> valueVoxels;
    
    typedef ImageType::IndexType IndexType;
    IndexType ind;
    ImageIterator it( binary, binary->GetRequestedRegion() );
    it.GoToBegin();
    while(!it.IsAtEnd())
    {
        if (it.Get()==true)
        {
            ind = it.GetIndex();
            valueVoxels.push_back(image->GetPixel(ind));
        }
        ++it;
    }
    
    double mean = 0.0, sum = 0.0, std = 0.0, nbVoxels = valueVoxels.size();
    for (int i=0; i<nbVoxels; i++)
        mean += valueVoxels[i];
    mean /= nbVoxels;
    for (int i=0; i<nbVoxels; i++) {
        sum += valueVoxels[i]*valueVoxels[i];
    }
    std = sqrt(sum/nbVoxels-mean*mean);
    
    /*ofstream myfile;
	myfile.open("StandardDeviation.txt", ios_base::app);
	myfile << ind[1] << " " << mean << " " << std << endl;
	myfile.close();*/
    
    return mean;
}
コード例 #8
0
void MyImageClass::SaveDICOMSeries(QString save_path, std::string subfolder)
{
    std::string output_directory = save_path.toStdString();
    output_directory +=subfolder;

    itksys::SystemTools::MakeDirectory( output_directory.c_str() );

    typedef signed short OutputPixelType;
    const unsigned int output_pixel_dimension = 2;

    typedef itk::Image < OutputPixelType, output_pixel_dimension > Image2Dtype;
    typedef itk::CastImageFilter<InternalImageType, ImageType> CastFilterType;

    typedef itk::ImageSeriesWriter < ImageType, Image2Dtype> SeriesWriterType;


    CastFilterType::Pointer caster = CastFilterType::New();
    SeriesWriterType::Pointer series_writer = SeriesWriterType::New();

    typedef itk::NumericSeriesFileNames NumericNamesGeneratorType;

    NumericNamesGeneratorType::Pointer namesGenerator = NumericNamesGeneratorType::New();

    itk::MetaDataDictionary &dict = gdcmIO_->GetMetaDataDictionary();
    std::string tagkey,value;
    tagkey = "0008|0060";
    value = "MR";
    itk::EncapsulateMetaData<std::string>(dict,tagkey,value);
    tagkey = "0008|0008";
    value = "DERIVED\\SECONDARY";
    itk::EncapsulateMetaData<std::string>(dict,tagkey,value);
    tagkey = "0008|0064";
    value = "DV";
    itk::EncapsulateMetaData<std::string>(dict,tagkey,value);

    caster->SetInput(reader_->GetOutput());
    series_writer->SetInput( caster->GetOutput());
    series_writer->SetImageIO(gdcmIO_);

    ImageType::RegionType region = reader_->GetOutput()->GetLargestPossibleRegion();
    ImageType::IndexType start = region.GetIndex();
    ImageType::SizeType size = region.GetSize();

    std::string format = output_directory;
    format += "/image%03d.dcm";

    namesGenerator->SetSeriesFormat(format.c_str());

    namesGenerator->SetStartIndex(start[2]);
    namesGenerator->SetEndIndex(start[2]+size[2]-1);
    namesGenerator->SetIncrementIndex(1);

    series_writer->SetFileNames (namesGenerator->GetFileNames());

    series_writer->SetMetaDataDictionaryArray(reader_->GetMetaDataDictionaryArray());

    try
    {
        series_writer->Update();
    }
    catch( itk::ExceptionObject &excp)
    {
        msg_box_.setText(excp.GetDescription());
        msg_box_.exec();
    }

}