DICOM Image is too dark with ITK - vtk

i am trying to read an image with ITK and display with VTK.
But there is a problem that has been haunting me for quite some time.
I read the images using the classes itkGDCMImageIO and itkImageSeriesReader.
After reading, i can do two different things:
1.
I can convert the ITK image to vtkImageData using itkImageToVTKImageFilter and the use vtkImageReslicer to get all three axes. Then, i use the classes vtkImageMapper, vtkActor2D, vtkRenderer and QVTKWidget to display the image.
In this case, when i display the images, there are several problems with colors. Some of them are shown very bright, others are so dark you can barely see them.
2.
The second scenario is the registration pipeline. Here, i read the image as before, then use the classes shown in the ITK Software Guide chapter about registration. Then i resample the image and use the itkImageSeriesWriter.
And that's when the problem appears. After writing the image to a file, i compare this new image with the image i used as input in the XMedcon software. If the image i wrote ahs been shown too bright in my software, there no changes when i compare both of them in XMedcon. Otherwise, if the image was too dark in my software, it appears all messed up in XMedcon.
I noticed, when comparing both images (the original and the new one) that, in both cases, there are changes in modality, pixel dimensions and glmax.
I suppose the problem is with the glmax, as the major changes occur with the darker images.
I really don't know what to do. Does this have something to do with color level/window? The most strange thing is that all the images are very similar, with identical tags and only some of them display errors when shown/written.

I'm not familiar with the particulars of VTK/ITK specifically, but it sounds to me like the problem is more general than that. Medical images have a high dynamic range and often the images will appear very dark or very bright if the window isn't set to some appropriate range. The DICOM tags Window Center (0028, 1050) and Window Width (0028, 1051) will include some default window settings that were selected by the modality. Usually these values are reasonable, but not always. See part 3 of the DICOM standard (11_03pu.pdf is the filename) section C.11.2.1.2 for details on how raw image pixels are scaled for display. The general idea is that you'll need to apply a linear scaling to the images to get appropriate pixel values for display.

What pixel types do you use? In most cases, it's simpler to use a floating point type while using ITK, but raw medical images are often in short, so that could be your problem.
You should also write the image to the disk after each step (in MHD format, for example), and inspect it with a viewer that's known to work properly, such as vv (http://www.creatis.insa-lyon.fr/rio/vv). You could also post them here as well as your code for further review.
Good luck!

For what you describe as your first issue:
I can convert the ITK image to vtkImageData using itkImageToVTKImageFilter and the use vtkImageReslicer to get all three axes. Then, i use the classes vtkImageMapper, vtkActor2D, vtkRenderer and QVTKWidget to display the image.
In this case, when i display the images, there are several problems with colors. Some of them are shown very bright, others are so dark you can barely see them.
I suggest the following: Check your window/level in VTK, they probably aren't adequate to your images. If they are abdominal tomographies window = 350 level 50 should be a nice color level.

Related

how do I perform image stitching with a reference image as a guide?

image stitching with a reference image.
I have multiple images of subject(bone), the images are of different sections of the subject as on a 3x3 matrix. I would like to stitch them together but the problem is they don't have any common feature, as the subject was cut into these sections using a saw. What i have is the image of subject before cutting and want to use it as a guide to stitch the images of sections together.
I have tried using Fiji imagej and searched the web for an alternative. imageJ can only do the job if it has common feature between images to work with. can someone point to some code in python or matlab that can do this or any software that could help.
'[Reference image][1] section (11) section (12) section (13) section (21) section (23) section (31)'
' [1]: https://i.stack.imgur.com/wQr09.jpg
I'm not able to add more than 8 links due to SO's policy. There are two more remaining, I'll add them soon. And the "section (22)" i.e centre position in the 3X3 matrix is empty.
Solutions for image processing needs like this vary wildly depending on whether you need a script to use just a few times, a software tool you'll use for a few weeks, or what could become lab automation software.
This seems to be a problem more of image matching rather than image stitching. By image matching I mean you need to find out how a subimage such as the bone section at (row 2, column 1) would match what is labeled as "4," the center left section, in the reference bone image.
The basic process:
Load your reference image as a 2D array (first converted to grayscale)
Load your first sample image of a subsection of bone.
Use an algorithm such as SIFT to determine the location, orientation, and scale to fit the bone subsection image onto the reference image.
Apply the fit criteria (x,y,rotation,scale) to the bone subsection image, transform it, and past it into a black image the same size as the reference image.
Continue the process above to fit all subsections.
(Optional) With all bone subsections fitted in place, perform additional image processing operations to improve the fit, fill in gaps, etc.
From your sample images it appears that the reference and the bone section images area taken using different lighting, sometimes with the flat portion of the bone slightly tilted relative to the camera's optical axis, etc., all of which makes the image match more difficult.
SIFT is an algorithm that could help here. Note that "scale invariant" is part of the algorithm name.
https://en.wikipedia.org/wiki/Scale-invariant_feature_transform
Given all that, your reference image and bone subsection images appear to be taken under very different circumstances, and that makes solving the problem harder than it needs to be. You'll have an easier time overall if you can control the conditions under which images are captured.
Capture all images with the same camera, with the same lighting, at roughly the same distance
For lighting, use something like a high-frequency diffuse fluorescent
Use the same background for every image (e.g. matte black)
Making this image match a robust process means paying attention to the physical setup as well as creating your image processing algorithm.
If you need a good reference for traditional image processing techniques, find a copy of Digital Image Processing by Gonzalez and Woods. Some time spent with that book will give you better answers faster than learning image processing piecemeal online.
For practical image processing that addresses real-world concerns for implementing even simple image processing algorithms, look for Machine Vision by Davies.
I would strongly urge that you NOT look into machine learning, or try to find an answer in a more advanced image processing textbook until you run into a roadblock with more traditional methods.

Is it possible to cut parts out of a picture and analyze them separately with python?

I am doing some studies on eye vascularization - my project contains a machine which can detect the different blood vessels in the retinal membrane at the back of the eye. What I am looking for is a possibility to segment the picture and analyze each segmentation on it`s own. The Segmentation consist of six squares wich I want to analyze separately on the density of white pixels.
I would be very thankful for every kind of input, I am pretty new in the programming world an I actually just have a bare concept on how it should work.
Thanks and Cheerio
Sam
Concept DrawOCTA PICTURE
You could probably accomplish this by using numpy to load the image and split it into sections. You could then analyze the sections using scikit-image or opencv (though this could be difficult to get working. To view the image, you can either save it to a file using numpy, or use matplotlib to open it in a new window.
First of all, please note that in image processing "segmentation" describes the process of grouping neighbouring pixels by context.
https://en.wikipedia.org/wiki/Image_segmentation
What you want to do can be done in various ways.
The most common way is by using ROIs or AOIs (region/area of interest). That's basically some geometric shape like a rectangle, circle, polygon or similar defined in image coordinates.
The image processing is then restricted to only process pixels within that region. So you don't slice your image into pieces but you restrict your evaluation to specific areas.
Another way, like you suggested is to cut the image into pieces and process them one by one. Those sub-images are usually created using ROIs.
A third option which is rather limited but sufficient for simple tasks like yours is accessing pixels directly using coordinate offsets and several nested loops.
Just google "python image processing" in combination with "library" "roi" "cropping" "sliding window" "subimage" "tiles" "slicing" and you'll get tons of information...

Turn an image into lines and circles

I need to be able to turn a black and white image into series of lines (start, end points) and circles (start point, radius). I have a "pen width" that's constant.
(I'm working with a screen that can only work with this kind of graphics).
Problem is, I don't want to over complicate things - I could represent any image with loads of small lines, but it would take a lot of time to draw, so I basically want to "approximate" the image using those lines and circles.
I've tried several approaches (guessing lines, working area by area, etc) but none had any reasonable results without using a lot of lines and circles.
Any idea on how to approach this problem?
Thanks in advance!
You don't specify what language you are working in here but I'd suggest OpenCV if possible. If not, then most decent CV libraries ought to support the features that I'm about to describe here.
You don't say if the input is already composed of simple shapes ( lines and polygons) or not. Assuming that it's not, i.e. it's a photo or frame from a video for example, you'll need to do some edge extraction to find the lines that you are going to model. Use a Canny or other edge detector to convert the image into a series of lines.
I suggest that you then extract Circles as they are the richest feature that you can model directly. You should consider using a Hough Circle transform to locate circles in your edge image. Once you've located them you need to remove them from the edge image (to avoid duplicating them in the line processing section below).
Now, for each pixel in the edge image that's 'on' you want to find the longest line segment that it's a part of. There are a number of algorithms for doing this, simplest would be Probabilistic Hough Transform (also available in openCV) to extract line segments which will give you control over the minimum length, allowed gaps etc. You may also want to examine alternatives like LSWMS which has OpenCV source code freely available.
Once you have extracted the lines and circles you can plot them into a new image or save the coordinates for your output device.

Gamma-correct zoomable image (dzi, etc) generator

I'm using MS Deep Zoom Composer to generate tiled image sets for megapixel sized images.
Right now I'm preparing a densely detailed black and white linedrawing.
The lack of gamma correction during resizing is very apparent;
while zooming the tiles appear to become brighter on higher zoom levels.
This makes the boundaries between tiles quite apparent during the loading stage.
While it does not in any way hurt usability it is a bit unsightly.
I am wondering if there are any alternatives to Deep Zoom Composer that do gamma correct resizing?
The vips deepzoom creator can do this.
You make a deepzoom pyramid like this:
vips dzsave somefile.tif pyr_name
and it'll read somefile.tif and write pyr_name.dzi and pyr_name_files, a folder containing the tiles. You can use a .zip extension to the pyramid name and it'll directly write an uncompressed zip file containing the whole pyramid --- this is a lot faster on Windows. There's a blog post with some more examples and explanation.
To make it shrink gamma corrected, you need to move your image to a linear colourspace for saving. The simplest is probably scRGB, that is, sRGB with linear light. You can do this with:
vips colourspace somefile.tif x.tif scrgb
and it'll write x.tif, an scRGB float tiff.
You can run the two operations in a single command by using .dz as the output file suffix. This will send the output of the colourspace transform to the deepzoom writer for saving. The deepzoom writer will use .jpg to save each tile, the jpeg writer knows that jpeg files can only be RGB, so it'll automatically turn the scRGB tiles back into plain sRGB for saving.
Put that all together and you need:
vips colourspace somefile.tif mypyr.dz scrgb
And that should build a pyramid with a linear-light shrink.
You can pass options to the deepzoom saver in square brackets after the filename, for example:
vips colourspace somefile.tif mypyr.dz[container=zip] scrgb
The blog post has the details.
update: the Windows binary is here, to save you hunting. Unzip somewhere, and vips.exe is in the /bin folder.
pamscale1 of the netpbm suite is quite well known not to screw up scaled images as you describe. It uses gamma correction instead of ill-concieved "high-quality filters" and other magic used to paper over incorrect scaling algorithms.
Of course you will need some scripting - it's not a direct replacement.
We maintain a list of DZI creation tools here:
http://openseadragon.github.io/examples/creating-zooming-images/
I don't know if any of them do gamma correction, but some of them might not have that issue to begin with. Also, many of them come with source, so you can add the gamma correction in yourself if need be.

detect color space with openCV

how can I see the color space of my image with openCV ?
I would like to be sure it is RGB, before to convert to another one using cvCvtColor() function
thanks
Unfortunately, OpenCV doesn't provide any sort of indication as to the color space in the IplImage structure, so if you blindly pick up an IplImage from somewhere there is just no way to know how it was encoded. Furthermore, no algorithm can definitively tell you if an image should be interpreted as HSV vs. RGB - it's all just a bunch of bytes to the machine (should this be HSV or RGB?). I recommend you wrap your IplImages in another struct (or even a C++ class with templates!) to help you keep track of this information. If you're really desperate and you're dealing only with a certain type of images (outdoor scenes, offices, faces, etc.) you could try computing some statistics on your images (e.g. build histogram statistics for natural RGB images and some for natural HSV images), and then try to classify your totally unknown image by comparing which color space your image is closer to.
txandi makes an interesting point. OpenCV has a BGR colorspace which is used by default. This is similar to the RGB colorspace except that the B and R channels are physically switched in the image. If the physical channel ordering is important to you, you will need to convert your image with this function: cvCvtColor(defaultBGR, imageRGB, CV_BGR2RGB).
As rcv said, there is no method to programmatically detect the color space by inspecting the three color channels, unless you have a priori knowledge of the image content (e.g., there is a marker in the image whose color is known). If you will be accepting images from unknown sources, you must allow the user to specify the color space of their image. A good default would be to assume RGB.
If you modify any of the pixel colors before display, and you are using a non-OpenCV viewer, you should probably use cvCvtColor(src,dst,CV_BGR2RGB) after you have finished running all of your color filters. If you are using OpenCV for the viewer or will be saving the images out to file, you should make sure they are in BGR color space.
The IplImage struct has a field named colorModel consisting of 4 chars. Unfortunately, OpenCV ignores this field. But you can use this field to keep track of different color models.
I basically split the channels and display each one to figure out the color space of the image I'm using. It may not be the best way, but it works for me.
For detailed explanation, you can refer the below link.
https://dryrungarage.wordpress.com/2018/03/11/image-processing-basics/

Resources