Dilate an image based on a distribution - matlab

I have an image that show some random filled circles (e.g. see here). I want to change these circles to make some irregular shapes. In other words, I want to define a distribution by which I can expand the circles. Clearly, the resulted new objects will not be circles anymore, because the generated objects are expanded based on a distribution which is variable; see this new deformed circle.
I was wondering if there is any method that can do this? In my first try, I tried to use image dilation in Matlab, but I have no idea on how the dilation "distribution" should be used.
IM2 = imdilate(IM,SE)

If you want to do it using dilation, a solution could be:
Let say Im is your original image
ImResult = Same(Im)
ImClone = Clone(Im)
Randomly delete pixels in ImClone. The number of pixels to delete may be a percentage, or whatever you prefer
ImDilate = Dilate(ImClone), with the structuring element of size N
Result = Maximum(Result, ImDilate)
If you want different size of deformations, then you iterate from step 3 to 6, with different structuring element sizes.
But what you want is more an elastic deformation. You should take a look to the free form deformation (FFD).

Related

Image segmentation algorithm in MATLAB

I need to implement an image segmentation function in MATLAB based on the principles of the connected components algorithm, but with a few modifications. This is intended for very simple, 2D images, with a background color and some objects in different colors.
The idea is that, taking the image as a matrix, I provide a tool to select the background color (it will vary for every image). Then, when the value of the color of the background of the image is selected, I have to segment all the objects in the image, and the result should be a labeled matrix, of the same size of the image, with 0's for the background, and a different number for each object.
This is a graphic example of what I mean:
I understand the idea of how to do it, but I do not know how to implement it on MATLAB. For each pixel (matrix position) I should mark it as visited and then if the value corresponds to the one of the background, assign 0, if not, assign another value. The objects can be formed by different colors, so in the end, I need to segment groups of adjacent pixels, whatever their color is. Also I have to use 8-connectivity, in order to count the green object of the example image as only one object and not 4 different ones. And also, the objects should be counted from top to bottom, and from left to right.
Is there a simple way of doing this in MATLAB? I know the bwlabel function, but it works for binary images only, so I'd like to adapt it to my case.
once you know the background color, you can easily convert your image into a binary mask of the same size:
bw=img!=bg_color;
Once you have a binary mask you can call bwlavel with 8-connectivity argument as you suggested yourself.
Note: you might want to convert your color image from RGB representation to an indexed image using rgb2ind before processing.

Interpolation between two images with different pixelsize

For my application, I want to interpolate between two images(CT to PET).
Therefore I map between them like that:
[X,Y,Z] = ndgrid(linspace(1,size(imagedata_ct,1),size_pet(1)),...
linspace(1,size(imagedata_ct,2),size_pet(2)),...
linspace(1,size(imagedata_ct,3),size_pet(3)));
new_imageData_CT=interp3(imagedata_ct,X,Y,Z,'nearest',-1024);
The size of my new image new_imageData_CT is similar to PET image. The problem is that data of my new image is not correct scaled. So it is compressed. I think the reason for that is that the pixelsize between the two images is different and not involved to the interpolation. So for example :
CT image size : 512x512x1027
CT voxel size[mm] : 1.5x1.5x0.6
PET image size : 192x126x128
PET voxel size[mm] : 2.6x2.6x3.12
So how could I take care about the voxel size regarding to the interpolation?
You need to perform a matching in the patient coordinate system, but there is more to consider than just the resolution and the voxel size. You need to synchronize the positions (and maybe the orientations also, but this is unlikely) of the two volumes.
You may find this thread helpful to find out which DICOM Tags describe the volume and how to calculate transformation matrices to use for transforming between the patient (x, y, z in millimeters) and volume (x, y, z in column, row, slice number).
You have to make sure that the volume positions are comparable as the positions of the slices in the CT and PET do not necsesarily refer to the same origin. The easy way to do this is to compare the DICOM attribute Frame Of Reference UID (0020,0052) of the CT and PET slices. For all slices that share the same Frame Of Reference UID, the position of the slice in the DICOM header refers to the same origin.
If the datasets do not contain this tag, it is going to be much more difficult, unless you just put it as an assumption. There are methods to deduce the matching slices of two different volumes from the contents of the pixel data referred to as "registration" but this is a science of its own. See the link from Hugues Fontenelle.
BTW: In your example, you are not going to find a matching voxel in both volumes for each position as the volumes have different size. E.g. for the x-direction:
CT: 512 * 1.5 = 768 millimeters
PET: 192 * 2.6 = 499 millimeters
I'll let to someone else answering the question, but I think that you're asking the wrong one. I lack context of course, but at first glance Matlab isn't the right tool for the job.
Have a look at ITK (C++ library with python wrappers), and the "Multi-modal 3D image registration" article.
Try 3DSlicer (it has a GUI for the previous tool)
Try FreeSurfer (similar, focused on brain scans)
After you've done that registration step, you could export the resulting images (now of identical size and spacing), and continue with your interpolation in Matlab if you wish (or with the same tools).
There is a toolbox in slicer called PETCTFUSION which aligns the PET scan to the CT image.
you can install it in slicer new version.
In the module's Display panel shown below, options to select a colorizing scheme for the PET dataset are provided:
Grey will provide white to black colorization, with black indicating the highest count values.
Heat will provide a warm color scale, with Dark red lowest, and white the highest count values.
Spectrum will provide a warm color scale that goes cooler (dark blue) on the low-count end to white at the highest.
This panel also provides a means to adjust the window and level of both PET and CT volumes.
I normally use the resampleinplace tool after the registration. you can find it in the package: registration and then, resample image.
Look at the screensht here:
If you would like to know more about the PETCTFUSION, there is a link below:
https://www.slicer.org/wiki/Modules:PETCTFusion-Documentation-3.6
Since slicer is compatible with python, you can use the python interactor to run your own code too.
And let me know if you face any problem

remove some top, down rows and right, and left some columns of jpg image border using matlab

I have RGB museum JPG Images. most of them have image footnotes on one or more sides, and I'd like to remove them. I do that manually using paint software. now I applied the following matlab code to remove the image footnotes automatically. I get a good result for some images but for others it not remove any border. Please, can any one help me by update this code to apply it for all images?
'rgbIm = im2double(imread('A3.JPG'));
hsv=rgb2hsv(rgbIm);
m = hsv(:,:,2);
foreground = m > 0.06; % value of background
foreground = bwareaopen(foreground, 1000); % or whatever.
labeledImage = bwlabel(foreground);
measurements = regionprops(labeledImage, 'BoundingBox');
ww = measurements.BoundingBox;
croppedImage = imcrop(rgbImage, ww);'
In order to remove the boundaries you could use "imclearborder", where it checks for labelled components at boundaries and clears them. Caution! if the ROI touches the boundary, it may remove. To avoid such instance you can use "imerode" with desired "strel" -( a line or disc) before clearing the borders. The accuracy or generalizing the method to work for all images depends entirely on "threshold" which separates the foreground and background.
More generic method could be - try to extract the properties of footnotes. For instance, If they are just some texts, you can easily remove them by using a edge detection and morphology opening with line structuring element along the cols. (basic property for text detection)
Hope it helps.
I could give you a clear idea or method if you upload the image.

MATLAB: How do I resize (connected) components in a 3D binary image sequence without changing the dimensions of the sequence?

I'd like to resize the components contained in a 3D binary image sequence without changing any of the dimensions of the sequence itself.
I'm not sure if I need to do it on a component-by-component basis, if yes, then how do I create a transform such that the resized components are re-positioned 'correctly' in the image sequence? By 'correctly', I mean with the same centre of mass as the original unprocessed components.
(If that last paragraph doesn't make sense then please ignore)
A 2D example: suppose I wanted to enlarge by 10% the white blobs in the following [295x445] image
How would you do this without making the image itself larger?
you could use the imdilate function to dilate the regions of interest. The examples in the webpage show how to use this function.

MATLAB - Restore central sub-section of an image

So, I have a 512x512 distorted image, but what I'm trying to do is restore only a 400x400 centrally-positioned subsection of the image while it is still distorted outside of it. How do I go about implementing something like that?
I was thinking to have a for loop within a for loop like
for row = 57:457
for col = 57:457
%some filter in here
end
end
But I'm not quite sure what to do next...
As a general rule, you can do a lot of things in MATLAB without loops using vectorization instead. As discussed in the comments below your question, there are filtering functions included with MATLAB such as medfilt2, wiener2 or imfilter which all work on two-dimensional images directly without the need for any loops.
To restore only the center part of your image, you apply the filter to the full image, store the result in a temporary variable and then copy over the part that you want into your distored image:
tmpimage = medfilt2(distortedimage);
finalimage = distortedimage;
finalimage(57:456,57:456)=tmpimage(57:456,57:456);
Of course if you don't care about edge effects during the reconstruction, you can just call the reconstruction for the part that interests you and avoid the tmpimage:
finalimage = distortedimage;
finalimage(57:456,57:456)=medfilt2(distortedimage(57:456,57:456));
Note how the sizes in an assignment need to match: you can't assign finalimage(57:456,57:456)=medfilt2(distortedimage) since the right-hand-size produces a 512-by-512 matrix which doesn't fit into the 400-by-400 center of finalimage.