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!
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.