ITK: Could not create IO object

2019-06-01 03:55发布

问题:

I am trying to calculate the gradient of an image. I tried this code on the sample image given (Gourds6.png).

I used cmake . to create the CMakeFiles and then make. Everything works fine and the executable file is created. Now when I run the code using command ./computeGradient Gourds6.png out.png 1.5, it complains that:

Error: 
itk::ImageFileWriterException (0x1446b40)
Location: "void itk::ImageFileWriter<TInputImage>::Write() [with TInputImage = itk::Image<float, 2u>]" 
File: /usr/local/include/ITK-4.3/itkImageFileWriter.hxx
Line: 152
Description:  Could not create IO object for file out.png
  Tried to create one of the following:
  You probably failed to set a file suffix, or
    set the suffix to an unsupported type.

I haven't done any change to this code. It should work. I don't know what is wrong with it :( Do you have any idea?

Also, why we don't need to update the reader to read the image? Why we only update the writer?

I appreciate for any help!

回答1:

The pixel type of the output file in this example of ITK is float. And write an image of float as a PNG image is not possible.

A list of supported file format and corresponding data type is given on the wiki of ITK.

To save this image of float, here are formats that are expected to work :

  • Analyze (.img)
  • DICOM (.dic : failed on my PC)
  • GIPL (.gipl)
  • MetaImage (mhd) (out.mhd+out.raw)
  • Nrrd (.nhdr, .nrrd)
  • Stimulate (.spr)
  • VTK (.vtk)

The VTK file format works well and may be opened by the paraview software.

To use a PNG format, the image should be casted to unsigned char type. It may be performed by the CastImageFilter(). See this example. Another solution is to use the RescaleIntensityImageFilter(). See this example.

This question and its answer (which happens to be mine) explains how to convert a float image type to a ùnsigned char` image type and save it as PNG.

typedef itk::RescaleIntensityImageFilter< FloatImageType, UCharImageType > RescaleFilterType;
RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();

rescaleFilter ->SetInput(importFilter->GetOutput());
rescaleFilter->SetOutputMinimum(0);
rescaleFilter->SetOutputMaximum(255);

typedef itk::ImageFileWriter<  UCharImageType  > WriterType;
WriterType::Pointer writer = WriterType::New();

writer->SetFileName( "output.png" );
writer->SetInput(rescaleFilter->GetOutput() );
writer->Update();

Finally, your last question : why we only update the writer ? As the writer is updated, it will fist check if its entries are up to date. If it is not the case, it will call filter->Update(), and so on.



标签: c++ image itk