ITK: Could not create IO object - c++

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

Related

Decrease in the quality of the image in flycapture

I am using flycapture sdk sample program to capture image form the flycapture.
My problem is that when i capture the image using the flycapture installed application the size of image is about 1.3 - 1.5 Mb. But when the take the same image using my program which consist of flycapture sample program. The size of the image is about 340K to 500K(max).Image format is .tiff
There is reduction in the quality of the image due to which my program is not able to get any valuable information form the image.
Using the following approach to save the image:
FlyCapture2::Camera camera;
FlyCapture2::Image image;
camera.RetrieveBuffer(&image);
ostringstream saveImage;
saveImage << "Image-" << "-" << i << ".tiff";
image.Save(saveImage.str().c_str());
And using the windows application following the approach mentioned in the link:
http://www.ptgrey.com/Content/Images/uploaded/FlyCapture2Help/flycapture/03demoprogram/saving%20images_flycap2.html
Please let me of any other details required
I am not 100% sure about this, since the documentation I found was for Java and not c++, but it is probably very similar.
You are using :
image.Save(saveImage.str().c_str());
to save your image, but are you sure it is saved as a tiff? the documentation (the java one), doesn't go deep into this, I am not sure if it is like OpenCV's imwrite that it automatically deduces the type and does it or not. So you should check that. There was one overload that you can pass the ImageFileFormat... this should be set to the TIFF one.
Another overload let's you specify the TIFF Options... in here you may tune it to have a different compression method. Notice that there is JPEG compression method... which would make something wayyy lighter but lossy... You may try with None, or the one that OpenCV uses LZW.

Trying to encode a GIF file using giflib

I am given image data and color table I am trying to export it as a single frame GIF using giflib. I looked into the API, but can't get it to work. The program crashes even at the first function:
GifFileType image_out;
int errorCode = 0;
char* fileName = "SomeName.gif";
image_out = *EGifOpenFileName(fileName,true, &errorCode);
It is my understanding that I first need to open a file by specifying it's name and then update it with fileHandle. Then Fill in the screen description, the extension block the image data and add the 3B ending to the file. Then use EGifSpew to export the whole gif. The problem is that I can't even use EGifOpenFileName(); The program crashes at that line.
Can someone help me the API of giflib? This problem is getting really frustrating.
Thanks.
EDIT:
For the purposes of simple encoding I do not want to specify a color table and I just want to encode a single frame GIF.
The prototype is:
GifFileType *EGifOpenFileName(char *GifFileName, bool GifTestExistance, int *ErrorCode)
You should write as
GifFileType* image_out = EGifOpenFileName(fileName,true, &errorCode);
Note GifFileType is not POD type so you should NOT copy like that.

vtkImageData to DcmDataset

I hold a volume image in a vtkImageData and need to convert it to DcmDataset (DCMTK). I know that I need to set general DICOM tags like patient data to the data set. That's not the problem.
Especially I'm interested in putting the pixel data to DcmDataset. Does anybody know an example or can explain how to do that?
Thanks in advance
Quoting from the DCMTK FAQ:
Is there a tool that converts common graphic formats like PGM/PPM,
PNG, TIFF, JPEG or BMP to DICOM?
No, unfortunately, there is no such tool in DCMTK. Currently, you have to write your own little program for that purpose.
The following code snippet from the toolkit's documentation could be a starting point:
char uid[100];
DcmFileFormat fileformat;
DcmDataset *dataset = fileformat.getDataset();
dataset->putAndInsertString(DCM_SOPClassUID, UID_SecondaryCaptureImageStorage);
dataset->putAndInsertString(DCM_SOPInstanceUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
dataset->putAndInsertString(DCM_PatientsName, "Doe^John");
/* ... */
dataset->putAndInsertUint8Array(DCM_PixelData, pixelData, pixelLength);
OFCondition status = fileformat.saveFile("test.dcm", EXS_LittleEndianExplicit);
if (status.bad())
cerr << "Error: cannot write DICOM file (" << status.text() << ")" << endl;
The current snapshot of the DCMTK (> version 3.5.4) contains a new
command line tool "img2dcm" that allows for converting JPEG images to
certain DICOM image SOP classes.
I would perhaps look first at the source code for img2dcm (documented here) to see the general process and then post back with any specific questions. IMHO, DCMTK is very powerful but extremely difficult to understand.

Saving output frame as an image file CUDA decoder

I am trying to save the decoded image file back as a BMP image using the code in CUDA Decoder project.
if (g_bReadback && g_ReadbackSID)
{
CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3 / 2), g_ReadbackSID);
long padded_size = (nWidth * nHeight * 3 );
CString output_file;
output_file.Format(_T("image/sample_45.BMP"));
SaveBMP(g_bFrameData[active_field],nWidth,nHeight,padded_size,output_file );
if (result != CUDA_SUCCESS)
{
printf("cuMemAllocHost returned %d\n", (int)result);
}
}
But the saved image looks like this
Can anybody help me out here what am i doing wrong .. Thank you.
After investigating further, there were several modifications I made to your approach.
pDecodedFrame is actually in some non-RGB format, I think it is NV12 format which I believe is a particular YUV variant.
pDecodedFrame gets converted to an RGB format on the GPU using a particular CUDA kernel
the target buffer for this conversion will either be a surface provided by OpenGL if g_bUseInterop is specified, or else an ordinary region allocated by the driver API version of cudaMalloc if interop is not specified.
The target buffer mentioned above is pInteropFrame (even in the non-interop case). So to make an example for you, for simplicity I chose to only use the non-interop case, because it's much easier to grab the RGB buffer (pInteropFrame) in that case.
The method here copies pInteropFrame back to the host, after it has been populated with the appropriate RGB image by cudaPostProcessFrame. There is also a routine to save the image as a bitmap file. All of my modifications are delineated with comments that include RMC so search for that if you want to find all the changes/additions I made.
To use, drop this file in the cudaDecodeGL project as a replacement for the videoDecodeGL.cpp source file. Then rebuild the project. Then run the executable normally to display the video. To capture a specific frame, run the executable with the nointerop command-line switch, eg. cudaDecodGL nointerop and the video will not display, but the decode operation and frame capture will take place, and the frame will be saved in a framecap.bmp file. If you want to change the specific frame number that is captured, modify the g_FrameCapSelect = 37; variable to some other number besides 37, and recompile.
Here is the replacement for videoDecodeGL.cpp I used pastebin because SO has a limit on the number of characters that can be entered in a question body.
Note that my approach is independent of whether readback is specified. I would recommend not using readback for this sequence.

converting a binary stream into a png format

I will try to be clear ....
My project idea is as follow :
I took several compression algorithms which I implemented using C++, after that I took a text file and applied to it the compression algorithms which I implemented, then applied several encryption algorithms on the compressed files, now I am left with final step which is converting these encrypted files to any format of image ( am thinking about png since its the clearest one ).
MY QUESTION IS :
How could I transform a binary stream into a png format ?
I know the image will look rubbish.
I want the binary stream to be converted to a an png format so I can view it as an image
I am using C++, hope some one out there can help me
( my previous thread which was closed )
https://stackoverflow.com/questions/5773638/converting-a-text-file-to-any-format-of-images-png-etc-c
thanx in advance
Help19
If you really really must store your data inside a PNG, it's better to use a 3rd party library like OpenCV to do the work for you. OpenCV will let you store your data and save it on the disk as PNG or any other format that it supports.
The code to do this would look something like this:
#include <cv.h>
#include <highgui.h>
IplImage* out_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, bits_pr_pixel);
char* buff = new char[width * height * bpp];
// then copy your data to this buff
out_image->imageData = buff;
if (!cvSaveImage("fake_picture.png", out_image))
{
std::cout << "ERROR: Failed cvSaveImage" << std::endl;
}
cvReleaseImage(&out_image);
The code above it's just to give you an idea on how to do what you need using OpenCV.
I think you're better served with a bi-dimensional bar code instead of converting your blob of data into a png image.
One of the codes that you could use is the QR code.
To do what you have in mind (storing data in an image), you'll need a lossless image format. PNG is a good choice for this. libpng is the official PNG encoding library. It's written in C, so you should be able to easily interface it with your C++ code. The homepage I linked you to contains links to both the source code so you can compile libpng into your project as well as a manual on how to use it. A few quick notes on using libpng:
It uses setjmp and longjmp for error handling. It's a little weird if you haven't worked with C's long jump functionality before, but the manual provides a few good examples.
It uses zlib for compression, so you'll also have to compile that into your project.