Send img VTK for ITK - c++

In VTK and ITK it is possible to pass images between them.
But, it's only possible to send image from ITK to VTK using
itk::ImageToVTKImageFilter.
Is it possible to send an image from vtk to itk ?

There is a filter, itk::ImportImageFilter, that takes the image buffer (that array returned by vtkImageData.GetScalarPointer()) and image properties like size, origin and spacing, and creates an itk::Image.
https://itk.org/Wiki/ITK/Examples/IO/ImportImageFilter shows how to import a C array to ITK as an image. Importing a vtkImageData is very similar.
Basically you will get the vtkImageData's spacing, origin, dimensions and use it as an input to the itk filter mentioned above. Pay attention to data type: if the vtkImageData's scalars are shorts the itk::image should be an itk::Image (3 if it's a 3d image, 2 if it's a 2d image).
Of course, syncronization between the vtk part of your pipeline and the itk part of your pipeline will have to be done manually, unless you can garantee that the imageData from which you get the pointer is always the same.

Here is an example :
http://itk.org/ITKExamples/src/Bridge/VtkGlue/ConvertvtkImageDataToAnitkImage/Documentation.html
HTH,
Simon

Related

Opengl cube map - different results for freeimage and stb image libs

I'm trying to understand cube maps. I have read the following tutorial: https://learnopengl.com/Advanced-OpenGL/Cubemaps My example program is very similar to the tutorial program but I use freeimage for loading textures. My cube map has inverted y view for each face. When I change texture library from stb image to freeimage in the tutorial program I also get inverted y view for each face. Does freeimage use some non-standard convention ? Why I get different results ?
I don't know if there is a standard for this, but I wouldn't say that FreeImage is mirroring the image vertically, it's just the way pixel data is stored.
If you want to read the data with an OpenGL generated texture, you may want to flip the images by code using FreeImage_FlipVertical before FreeImage_GetBits. I guess you are using FreeImage_GetBits to deliver the data to the texture generated in OpenGL, if you are reading the image with scan lines, you can load the data from the bottom up.
Heads-up: If you use multiple formats of images It is likely that you also have other problems regarding the way data is stored, so just to let you know, when you use GetBits and GetScanLine, in the official FreeImage documentation says "It is up to you to interpret these bytes correctly, according to the results of FreeImage_GetBPP, FreeImage_GetRedMask, FreeImage_GetGreenMask and FreeImage_GetBlueMask" so if you have other problems loading the image to OpenGL you may want to check the examples here for interpreting the data:
http://freeimage.sourceforge.net/documentation.html

Read DICOM in C++ and convert to OpenCV

I would like to read DICOM images in C++ and manipulate them using opencv.
I managed to read a dicom image using DCMTK however, I am unsure how to convert it to an opencv Mat.
The following is what I have so far:
DicomImage DCM_image("test.dcm");
cv::Mat image(int(DCM_image.getWidth()), int(DCM_image.getHeight()), CV_8U, (uchar*)DCM_image.getOutputData(8));
which results in the following:
In a DICOM viewer, it looks as follows:
After normalising, the grayed image appears as follows:
Any help would be greatly appreciated.
The main problem I can see now is the difference of pixel value ranges (depths).
AFAIK, DICOM can have a rather big depth (16 bit), and you are trying to fit in into CV_8U, which is only 8 bit. You can get DicomImage instance's depth using DicomImage::getDepth(), and then create a cv::Mat with appropriate depth to hold your image data.
You may also need to normalize the data to maximally utilize you available range, so that the display with cv::imshow() would look as expected.
So:
Do DicomImage::getDepth() on your DCM_image
Create a cv::Mat with sufficient depth to hold your data
Scale, if necessary
Before calling DicomImage::getOutputData() on a monochrome DICOM image, you should make sure that you've selected an appropriate VOI transformation (e.g. Window Center & Width). This could be done by DicomImage::setMinMaxWindow(), DicomImage::setWindow() etc. See documentation of the DicomImage class.
Please note, however, that DicomImage::getOutputData() always returns rendered pixel data, i.e. not the original Pixel Data that is stored in the DICOM dataset.
U need to read the data type in DICOM image encoding an convert that to opencv type Mat. The opencv docs provides the entire information on their Mat header.

Draw dicom raw data in qt

I'm trying to develop a tool to visualize dicom images
I'm using itk library but i have some problem drawing the data
I'm using gdcm library provided by itk library as a third party lib.
I'm reading the image correctly i retrieved the tags ... but when i retrieve the pixels data using
unsigned short buffer* = ImageFileReader<Image<unsigned short,2>>->GetOutput()->getBufferPointer();
and i put it in QPixmap or QImage i tried both,Qpixelmap when i do loadData i get false as a return value and using QImage, the app crashes !
Any help ? thank you
Look at this example, http://gdcm.sourceforge.net/html/ConvertToQImage_8cxx-example.html
Just use gdcm to read the image and convert it to qimage.
Keep in mind that dicom images are not an image format that qt can draw, you need a conversion step.

loadRawData Memory issue in ogre while load opencv frames

I am capturing images in real time using OpenCV, and I want to show these images in the OGRE window as a background. So, for each frame the background will change.
I am trying to use MemoryDataStream along with loadRawData to load the images into an OGRE window, but I am getting the following error:
OGRE EXCEPTION(2:InvalidParametersException): Stream size does not
match calculated image size in Image::loadRawData at
../../../../../OgreMain/src/OgreImage.cpp (line 283)
An image comes from OpenCV with a size of 640x480 and frame->buffer is a type of Mat in OpenCV 2.3. Also, the pixel format that I used in OpenCV is CV_8UC3 (i.e., each pixel is 8-bits and each pixel contains 3 channels ( B8G8R8 ) ).
Ogre::MemoryDataStream* videoStream = new Ogre::MemoryDataStream((void*)frame->buffer.data, 640*480*3, true);
Ogre::DataStreamPtr ptr(videoStream,Ogre::SPFM_DELETE);
ptr->seek(0);
Ogre::Image* image = new Ogre::Image();
image->loadRawData(ptr,640, 480,Ogre::PF_B8G8R8 );
texture->unload();
texture->loadImage(*image)
Why I always getting this memory error?
Quick idea, maybe memory 4-byte alignment issues ?
see Link 1 and
Link 2
I'm not an Ogre expert, but does it work if you use loadDynamicImage instead?
EDIT : Just for grins try using the Mat fields to setup the buffer:
Ogre::Image* image = new Ogre::Image();
image->loadDynamicImage((uchar*)frame->buffer.data, frame->buffer.cols, frame->buffer.rows, frame->buffer.channels(), Ogre::PF_B8G8R8);
This will avoid copying the image data, and should let the Mat delete it's contents later.
I had similar problems to get image data into OGRE, in my case the data came from ROS (see ros.org). The thing is that your data in frame->buffer is not RAW, but has a file header etc.
I think my solution was to search the data stream for the beginning of the image (by finding the appropriate indicator in the data block, e.g. 0x4D 0x00), and inserting the data from this point on.
You would have to find out were in your buffer the header ends and where your data begins.

How can I access the JPEG image pixels as a 3D array like we do in MATLAB?

I want to process an image in C++. How can I access the 3D array representing the JPEG image as is done in MATLAB?
I'd suggest using OpenCV for the task; C++ documentation is available here. The relevant (I believe) data structure which you'd have to use is the Point3_ class, which represents a 3D point in the image.
Well, I've never used MATLAB for such a task, but in C++ you will need some JPEG loader library like OpenIL or FreeImage. These will allow you to access the picture as byte arrays.
FreeImage's FreeImage_GetBits function has a detailed example in the documentation on how to access per pixel per channel data.
BTW, if you plan to do image processing in C/C++, I'd suggest you to check out the Insight Segmentation and Registration Toolkit and OpenCV.