writing .png image not working

Hi everyone! I’m trying to write Cannyfilter image as a .png image.

It has no bugs. But it does not work. Here is the message:

itk::ExceptionObject (000000926B4FD6A0)

Location: "void __cdecl itk::PNGImageIO::WriteSlice(const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,const void *)"

File: c:\itk\src\modules\io\png\src\itkpngimageio.cxx

Line: 519

Description: PNG supports unsigned char and unsigned short

I changed the type of pixeltype: to unsigned char or unsigned short, but I got the error: cannot convert from ‘itk::Concept::lsFloatingPoint<unsigned char>::Constraints::FalseT’ to ‘itk::Concept::Detail::UniqueType_bool<true>’

I get the same error with writing .jpg or .dcm image.

This is the example code I run:

#include "itkImage.h"

#include "itkImageFileReader.h"

#include "itkImageFileWriter.h"

#include "itkRescaleIntensityImageFilter.h"

#include "itkCastImageFilter.h"

#include "itkCannyEdgeDetectionImageFilter.h"

#include "itksys/SystemTools.hxx"

#include <sstream>

#include "QuickView.h"

int main(int argc, char *argv[])

{

if(argc < 2)

{

std::cerr << "Usage: " << argv[0]

<< " Filename [variance lower_threshold upper_threshold]"

<< std::endl;

return EXIT_FAILURE;

}

std::string inputFileName = argv[1];

double variance = 2.0;

double upperThreshold = 0.0;

double lowerThreshold = 0.0;

if (argc > 2)

{

variance = atof(argv[2]);

}

if (argc > 3)

{

lowerThreshold = atof(argv[3]);

}

if (argc > 4)

{

upperThreshold = atof(argv[4]);

}

typedef itk::Image<float, 2> FloatImageType;

typedef itk::Image<unsigned char, 2> ImageType;

typedef itk::ImageFileReader<FloatImageType> ReaderType;

ReaderType::Pointer reader = ReaderType::New();

reader->SetFileName(inputFileName);

typedef itk::CannyEdgeDetectionImageFilter <FloatImageType, ImageType> CannyEdgeDetectionImageFilterType;

CannyEdgeDetectionImageFilterType::Pointer cannyFilter = CannyEdgeDetectionImageFilterType::New();

cannyFilter->SetInput(reader->GetOutput());

cannyFilter->SetVariance( variance );

cannyFilter->SetUpperThreshold( upperThreshold );

cannyFilter->SetLowerThreshold( lowerThreshold );

QuickView viewer;

//viewer.AddImage<DoubleImageType>(reader->GetOutput());

//viewer.AddImage<DoubleImageType>(cannyFilter->GetOutput());

viewer.AddImage(

reader->GetOutput(), true,

itksys::SystemTools::GetFilenameName(inputFileName));

std::stringstream desc;

desc << "Canny image, variance = "<< variance<< std::endl

<< "upperThreshold = " <<upperThreshold << std::endl

<<"lowerThreshold = " <<lowerThreshold;

viewer.AddImage(cannyFilter->GetOutput(), true, desc.str());

std::stringstream ss;

ss << "canny1.png";

typedef itk::ImageFileWriter<ImageType> FileWriteType;

FileWriteType::Pointer write = FileWriteType::New();

write->SetFileName(ss.str());

write->SetInput(cannyFilter->GetOutput());

try

{

write->Update();

}

catch (itk::ExceptionObject & err)

{

std::cerr << "ExceptionObject caught !" << std::endl;

std::cerr << err << std::endl;

viewer.Visualize();

return EXIT_SUCCESS;

}

}

Thank you for your help! :slight_smile:

You need to rescale cannyFilter->GetOutput() to unsigned char. Read rescale filter’s docs and look at examples linked in it.

The IO infrastructure can cast between integral types. Floating point types are not handled due to varying range standards, e.g. some filters produce output in [0,1] range, while others might utilize ±inf.

2 Likes