[Insight-users] reading a vtk image
Will Schroeder
will.schroeder@kitware.com
Thu, 11 Apr 2002 11:21:17 -0400
--=====================_-73023402==_
Content-Type: text/plain; charset="us-ascii"; format=flowed
Hi Pieter-
I've fixed the itkVTKImageIO reader in the beta branch. I also made some
other changes to your example (use of std:: in front of cerr and endl; and
the itkImageFileWriter requires an ImageIOBase subclass to be created).
I''ll check them in later, in the mean time here are the changes. Please
let me know immediately if you find problems.
Will
At 02:33 PM 4/11/2002 +0200, Pieter Vos wrote:
>Hi,
>
>Here are the file needed for the test.
>Good luck!
>
>Bye,
>
>Pieter Vos
>AZN Radboud
>Nijmegen
>The Netherlands
--=====================_-73023402==_
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment; filename="reader.cxx"
/*=========================================================================
Pieter Vos
AZN Radboud
Nijmegen The Netherlands
mailto: pieterv@radiology.azn.nl
Thanks for the good work!
=========================================================================*/
#include <iostream>
#include "itkImageFileWriter.h"
#include "itkImageFileReader.h"
#include "itkVTKImageIO.h"
#include <itkImage.h>
// Define the dimension of the images
const unsigned int myDimension = 3;
//Declare the types of the images
typedef itk::Image<float, myDimension> FloatImageType;
int main()
{
// Create a mapper (in this case a reader). A mapper
// is templated on the input type.
//
itk::VTKImageIO::Pointer vtkIO;
vtkIO = itk::VTKImageIO::New();
// Create a source object (in this case a reader)
itk::ImageFileReader<FloatImageType>::Pointer reader;
reader = itk::ImageFileReader<FloatImageType>::New();
reader->SetImageIO(vtkIO);
std::cout <<"Getting file"<<std::endl;
reader->SetFileName("sphere.vtk");
try{
reader->Update();
} catch (itk::ExceptionObject & e) {
std::cerr << "exception in file reader " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return EXIT_FAILURE;
}
std::cout <<"Done with file"<<std::endl;
////////////Now write the file//////////////////////
// Create a source object (in this case a writer)
itk::VTKImageIO::Pointer vtkIO2;
vtkIO2 = itk::VTKImageIO::New();
itk::ImageFileWriter<FloatImageType>::Pointer writer;
writer = itk::ImageFileWriter<FloatImageType>::New();
writer->SetInput(reader->GetOutput());
writer->SetFileName("sphere2.vtk");
writer->SetImageIO(vtkIO2);
try{
writer->Write();
} catch (itk::ExceptionObject & e) {
std::cerr << "exception in file writer " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
--=====================_-73023402==_
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment; filename="itkVTKImageIO.h"
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkVTKImageIO.h,v $
Language: C++
Date: $Date: 2002/02/26 22:08:29 $
Version: $Revision: 1.5.2.1 $
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
Portions of this code are covered under the VTK copyright.
See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __itkVTKImageIO_h
#define __itkVTKImageIO_h
#include "itkImageIOBase.h"
#include <fstream>
namespace itk
{
class ITK_EXPORT VTKImageIO : public ImageIOBase
{
public:
/** Standard class typedefs. */
typedef VTKImageIO Self;
typedef ImageIOBase Superclass;
typedef SmartPointer<Self> Pointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(VTKImageIO, Superclass);
/*-------- This part of the interface deals with reading data. ------ */
/** Determine the file type. Returns true if this ImageIO can read the
* file specified. */
virtual bool CanReadFile(const char*);
/** Set the spacing and dimesion information for the current filename. */
virtual void ReadImageInformation();
/** Reads the data from disk into the memory buffer provided. */
virtual void Read(void* buffer);
/*-------- This part of the interfaces deals with writing data. ----- */
/** Determine the file type. Returns true if this ImageIO can read the
* file specified. */
virtual bool CanWriteFile(const char*);
/** Writes the data to disk from the memory buffer provided. Make sure
* that the IORegion has been set properly. */
virtual void Write(void* buffer);
protected:
VTKImageIO();
~VTKImageIO();
void PrintSelf(std::ostream& os, Indent indent) const;
bool OpenVTKFileForReading(std::ifstream& os, const char* filename);
bool OpenVTKFileForWriting(std::ofstream& os, const char* filename);
void InternalReadImageInformation(std::ifstream& file);
private:
VTKImageIO(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace itk
#endif // __itkVTKImageIO_h
--=====================_-73023402==_
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment; filename="itkImageFileWriter.txx"
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkImageFileWriter.txx,v $
Language: C++
Date: $Date: 2002/02/26 22:08:27 $
Version: $Revision: 1.5.2.1 $
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkImageFileWriter.h"
#include "itkDataObject.h"
#include "itkImageIOFactory.h"
#include "itkCommand.h"
namespace itk
{
//---------------------------------------------------------
template <class TInputImage>
ImageFileWriter<TInputImage>
::ImageFileWriter():
m_FileName(""),m_FilePrefix(""),m_FilePattern(""),
m_ImageIO(0), m_UserSpecifiedImageIO(false),
m_Region(0), m_UserSpecifiedRegion(false)
{
}
//---------------------------------------------------------
template <class TInputImage>
ImageFileWriter<TInputImage>
::~ImageFileWriter()
{
}
//---------------------------------------------------------
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::SetInput(InputImageType *input)
{
this->ProcessObject::SetNthInput(0, input);
}
//---------------------------------------------------------
template <class TInputImage>
ImageFileWriter<TInputImage>::InputImagePointer
ImageFileWriter<TInputImage>
::GetInput()
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast<TInputImage*>
(this->ProcessObject::GetInput(0).GetPointer());
}
//---------------------------------------------------------
template <class TInputImage>
ImageFileWriter<TInputImage>::InputImagePointer
ImageFileWriter<TInputImage>
::GetInput(unsigned int idx)
{
return static_cast<TInputImage*>
(this->ProcessObject::GetInput(idx).GetPointer());
}
//---------------------------------------------------------
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::Write()
{
InputImagePointer input = this->GetInput();
if ( input == 0 )
{
itkExceptionMacro(<<"No input to writer!");
return;
}
input->Update();
if ( m_ImageIO == 0 )
{
itkExceptionMacro(<<"No ImageIO set, or none could be created.");
return;
}
// Make sure region is within the image, crop if necessary
ImageIORegion ioRegion(TInputImage::ImageDimension);
ImageRegion<TInputImage::ImageDimension> region =
input->GetLargestPossibleRegion();
const double *spacing = input->GetSpacing();
const double *origin = input->GetOrigin();
m_ImageIO->SetNumberOfDimensions(TInputImage::ImageDimension);
for(unsigned int i=0; i<TInputImage::ImageDimension; i++)
{
ioRegion.SetSize(i,region.GetSize(i));
ioRegion.SetIndex(i,region.GetIndex(i));
m_ImageIO->SetDimensions(i,region.GetSize(i));
m_ImageIO->SetSpacing(i,spacing[i]);
m_ImageIO->SetOrigin(i,origin[i]);
}
this->Write(ioRegion);
}
//---------------------------------------------------------
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::Write(const ImageIORegion &ioRegion)
{
InputImagePointer input = this->GetInput();
// make sure input is available
if ( input == 0 )
{
itkExceptionMacro(<< "No input to writer!");
return;
}
if ( m_ImageIO == 0 )
{
itkExceptionMacro(<<"No ImageIO set, or none could be created.");
return;
}
// Check to see if we can write the file given the name or prefix
//
if ( m_FileName == "" && m_FilePrefix == "" )
{
itkExceptionMacro(<<"No filename or file prefix specified");
return;
}
m_ImageIO->SetIORegion(ioRegion);
// make sure the data is up-to-date
input->Update();
// Notify start event observers
this->InvokeEvent( StartEvent() );
// Actually do something
this->GenerateData();
// Notify end event observers
this->InvokeEvent( EndEvent() );
// Release upstream data if requested
if ( this->GetInput(0)->ShouldIReleaseData() )
{
this->GetInput(0)->ReleaseData();
}
}
//---------------------------------------------------------
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::GenerateData()
{
InputImagePointer input = this->GetInput();
itkDebugMacro(<<"Writing file" << m_FileName);
// Make sure that the image is the right type and no more than
// four components.
typedef typename InputImageType::PixelType ScalarType;
// Set the pixel and component type; the number of components.
m_ImageIO->SetPixelType(typeid(ScalarType));
// Setup the image IO for writing.
//
m_ImageIO->SetFileName(m_FileName.c_str());
m_ImageIO->SetFilePrefix(m_FilePrefix.c_str());
//okay, now extract the data as a raw buffer pointer
void* dataPtr = (void*) input->GetBufferPointer();
m_ImageIO->Write(dataPtr);
}
//---------------------------------------------------------
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << "File Name: "
<< (m_FileName.data() ? m_FileName.data() : "(none)") << std::endl;
os << indent << "File Prefix: "
<< (m_FilePrefix.data() ? m_FilePrefix.data() : "(none)") << std::endl;
os << indent << "File Pattern: "
<< (m_FilePattern.data() ? m_FilePattern.data() : "(none)") << std::endl;
os << indent << "Image IO: ";
if ( m_ImageIO == 0 )
{
os << "(none)\n";
}
else
{
os << m_ImageIO << "\n";
}
}
} // end namespace itk
--=====================_-73023402==_
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: attachment; filename="itkVTKImageIO.cxx"
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkVTKImageIO.cxx,v $
Language: C++
Date: $Date: 2002/02/26 22:08:29 $
Version: $Revision: 1.7.2.1 $
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
Portions of this code are covered under the VTK copyright.
See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkVTKImageIO.h"
#include <cstdio>
namespace itk
{
VTKImageIO::VTKImageIO()
{
this->SetNumberOfDimensions(2);
m_ByteOrder = LittleEndian;
m_FileType = ASCII;
}
VTKImageIO::~VTKImageIO()
{
}
bool VTKImageIO::OpenVTKFileForReading(std::ifstream& os,
const char* filename)
{
// Make sure that we have a file to
if ( filename == "" )
{
itkExceptionMacro(<<"A FileName must be specified.");
return false;
}
// Close file from any previous image
if ( os.is_open() )
{
os.close();
}
// Open the new file for reading
itkDebugMacro(<< "Initialize: opening file " << filename);
// Actually open the file
int openMode = std::ios::in;
#ifdef _WIN32
openMode |= std::ios::binary;
#endif
#if defined(__GNUC__) && __GNUC__ >= 3
os.open(filename, static_cast<std::ios_base::openmode>(openMode));
#else
os.open(filename, openMode);
#endif
if ( os.fail() )
{
itkExceptionMacro(<< "Could not open file for reading: " << filename);
return false;
}
return true;
}
bool VTKImageIO::OpenVTKFileForWriting(std::ofstream& os,
const char* filename)
{
// Make sure that we have a file to
if ( filename == "" )
{
itkExceptionMacro(<<"A FileName must be specified.");
return false;
}
// Close file from any previous image
if ( os.is_open() )
{
os.close();
}
// Open the new file for writing
itkDebugMacro(<< "Initialize: opening file " << filename);
// Actually open the file
int openMode = std::ios::out;
#ifdef _WIN32
openMode |= std::ios::binary;
#endif
#if defined(__GNUC__) && __GNUC__ >= 3
os.open(filename, static_cast<std::ios_base::openmode>(openMode));
#else
os.open(filename, openMode);
#endif
if ( os.fail() )
{
itkExceptionMacro(<< "Could not open file for writing: " << filename);
return false;
}
return true;
}
bool VTKImageIO::CanReadFile(const char* filename)
{
std::ifstream file;
char buffer[256];
std::string fname(filename);
if ( fname.find(".vtk") >= fname.length() )
{
return false;
}
if ( ! this->OpenVTKFileForReading(file, filename) )
{
return false;
}
// Check to see if its a vtk structured points file
file.getline(buffer,255);
file.getline(buffer,255);
file.getline(buffer,255);
file.getline(buffer,255);
fname = buffer;
if ( fname.find("STRUCTURED_POINTS") < fname.length() ||
fname.find("structured_points") < fname.length() )
{
return true;
}
else
{
return false;
}
}
void VTKImageIO::InternalReadImageInformation(std::ifstream& file)
{
char line[255];
std::string text;
if ( ! this->OpenVTKFileForReading(file, m_FileName.c_str()) )
{
itkExceptionMacro(<< "Cannot read requested file");
}
file.getline(line,255);
file.getline(line,255);
file.getline(line,255);
text = line;
if ( text.find("ASCII") < text.length() ||
text.find("ascii") < text.length() )
{
this->SetFileTypeToASCII();
}
else if ( text.find("BINARY") < text.length() ||
text.find("binary") < text.length() )
{
this->SetFileTypeToBinary();
}
else
{
itkExceptionMacro(<< "Unrecognized type");
}
file.getline(line,255);
text = line;
if ( text.find("STRUCTURED_POINTS") >= text.length() &&
text.find("structured_points") >= text.length() )
{
itkExceptionMacro(<< "Not structured points, can't read");
}
//extract dimensions, spacing, origin
unsigned int dims[3];
float spacing[3];
float origin[3];
file.getline(line,255);
text = line;
int i;
if ( text.find("DIMENSIONS") < text.length() ||
text.find("dimensions") < text.length() )
{
sscanf(line, "%*s %d %d %d", dims, dims+1, dims+2);
if ( dims[2] <= 1 )
{
this->SetNumberOfDimensions(2);
}
else
{
this->SetNumberOfDimensions(3);
}
for ( i=0; i < m_NumberOfDimensions; i++ )
{
m_Dimensions[i] = dims[i];
}
}
else
{
itkExceptionMacro(<<"No dimensions defined");
}
// set values in case we don't find them
m_Spacing[0] = 1.0;
m_Spacing[1] = 1.0;
m_Spacing[2] = 1.0;
m_Origin[0] = 0.0;
m_Origin[1] = 0.0;
m_Origin[2] = 0.0;
file.getline(line,255);
text = line;
for ( bool readScalars=false; !readScalars; )
{
if ( text.find("SPACING") < text.length() ||
text.find("spacing") < text.length() )
{
sscanf(line, "%*s %f %f %f", spacing, spacing+1, spacing+2);
for ( i=0; i < m_NumberOfDimensions; i++ )
{
m_Spacing[i] = spacing[i];
}
}
else if ( text.find("ORIGIN") < text.length() ||
text.find("origin") < text.length() )
{
sscanf(line, "%*s %f %f %f", origin, origin+1, origin+2);
for ( i=0; i < m_NumberOfDimensions; i++ )
{
m_Origin[i] = origin[i];
}
}
else if ( text.find("SCALARS") < text.length() ||
text.find("scalars") < text.length() )
{
readScalars = true;
char pixelType[256];
sscanf(line, "%*s %*s %s", pixelType);
text = pixelType;
if ( text.find("float") < text.length() )
{
SetPixelType(FLOAT);
SetComponentType(FLOAT);
}
else if ( text.find("double") < text.length() )
{
SetPixelType(DOUBLE);
SetComponentType(DOUBLE);
}
else if ( text.find("unsigned_char") < text.length() )
{
SetPixelType(UCHAR);
SetComponentType(UCHAR);
}
else if ( text.find("char") < text.length() )
{
SetPixelType(CHAR);
SetComponentType(CHAR);
}
else if ( text.find("unsigned_short") < text.length() )
{
SetPixelType(USHORT);
SetComponentType(USHORT);
}
else if ( text.find("short") < text.length() )
{
SetPixelType(SHORT);
SetComponentType(SHORT);
}
else if ( text.find("unsigned_int") < text.length() )
{
SetPixelType(UINT);
SetComponentType(UINT);
}
else if ( text.find("int") < text.length() )
{
SetPixelType(INT);
SetComponentType(INT);
}
else if ( text.find("unsigned_long") < text.length() )
{
SetPixelType(ULONG);
SetComponentType(ULONG);
}
else if ( text.find("long") < text.length() )
{
SetPixelType(LONG);
SetComponentType(LONG);
}
else
{
itkExceptionMacro(<<"Unrecognized type");
}
}//found scalars
file.getline(line,255);
text = line;
}
}
void VTKImageIO::Read(void* buffer)
{
std::ifstream file;
this->InternalReadImageInformation(file);
//We are positioned at the data. The data is read depending on whether
//it is ASCII or binary.
if ( m_FileType == ASCII )
{
this->ReadBufferAsASCII(file, buffer, this->GetComponentType(),
this->GetImageSizeInComponents());
}
else
{
file.read(static_cast<char*>(buffer), this->GetImageSizeInBytes());
}
}
void VTKImageIO::ReadImageInformation()
{
std::ifstream file;
this->InternalReadImageInformation(file);
}
bool VTKImageIO::CanWriteFile(const char*)
{
if ( m_FileName != "" &&
m_FileName.find(".vtk") < m_FileName.length() )
{
return true;
}
return false;
}
void VTKImageIO::Write(void* buffer)
{
std::ofstream file;
if ( ! this->OpenVTKFileForWriting(file,m_FileName.c_str()) )
{
return;
}
// Check the image region for proper dimensions, etc.
unsigned int numDims = this->GetNumberOfDimensions();
if ( numDims < 2 || numDims > 3 )
{
itkExceptionMacro(<<"VTK Writer can only write 2 or 3-dimensional images");
return;
}
ImageIORegion ioRegion = this->GetIORegion();
// Write the VTK header information
file << "# vtk DataFile Version 3.0\n";
file << "VTK File Generated by Insight Segmentation and Registration Toolkit (ITK)\n";
if ( this->GetFileType() == ASCII ) { file << "ASCII\n"; }
else { file << "BINARY\n"; }
// Write characteristics of the data
file << "DATASET STRUCTURED_POINTS\n";
if ( numDims == 2 )
{
file << "DIMENSIONS " << this->GetDimensions(0) << " "
<< this->GetDimensions(1) << " 1\n";
file << "SPACING " << m_Spacing[0] << " " << m_Spacing[1] << " 1.0\n";
file << "ORIGIN " << m_Origin[0] << " " << m_Origin[1] << " 0.0\n";
}
else //numDims == 3
{
file << "DIMENSIONS " << this->GetDimensions(0) << " "
<< this->GetDimensions(1) << " " << this->GetDimensions(2) << "\n";
file << "SPACING " << m_Spacing[0] << " "
<< m_Spacing[1] << " " << m_Spacing[2] << "\n";
file << "ORIGIN " << m_Origin[0] << " "
<< m_Origin[1] << " " << m_Origin[2] << "\n";
}
file << "POINT_DATA " << this->GetImageSizeInPixels() << "\n";
file << "SCALARS scalars "
<< this->ReturnTypeAsString(this->GetComponentType()) << " "
<< this->GetNumberOfComponents() << "\n";
file << "LOOKUP_TABLE default\n";
// Write the actual pixel data
if ( m_FileType == ASCII )
{
this->WriteBufferAsASCII(file, buffer, this->GetComponentType(),
this->GetImageSizeInComponents());
}
else //binary
{
file.write(static_cast<char*>(buffer), this->GetImageSizeInBytes());
}
}
void VTKImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // end namespace itk
--=====================_-73023402==_--