c++imageitk

ITK: Could not create IO object


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 don't we need to update the reader to read the image? Why do we only update the writer?

I appreciate for any help!


Solution

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

    A list of supported files formats and corresponding data types is given on the wiki of ITK.

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

    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 do we only update the writer ? As the writer is updated, it will first check if its entries are up to date. If it is not the case, it will call filter->Update(), and so on.