Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing background and measuring features of an image in MATLAB

I'm trying to measure the areas of each particle shown in this image:

enter image description here

I managed to get the general shape of each particle using MSER shown here:

enter image description here

but I'm having trouble removing the background. I tried using MATLAB's imfill, but it doesn't fill all the particles because some are cut off at the edges. Any tips on how to get rid of the background or find the areas of the particles some other way? Cheers.

Edit: This is what imfill looks like:

enter image description here

Edit 2: Here is the code used to get the outline. I used this for the MSER.

%Compute region seeds and elliptial frames.
%MinDiversity = how similar to its parent MSER the region is
%MaxVariation = stability of the region
%BrightOnDark is used as the  void is primarily dark. It also prevents dark
%patches in the void being detected.
[r,f] = vl_mser(I,'MinDiversity',0.7,...
                'MaxVariation',0.2,...
                'Delta',10,...
                'BrightOnDark',1,'DarkOnBright',0) ;

%Plot region frames, but not used right now
%f = vl_ertr(f) ;
%vl_plotframe(f) ;

%Plot MSERs
M = zeros(size(I)) ; %M = no of overlapping extremal regions

for x=r'
 s = vl_erfill(I,x) ;
 M(s) = M(s) + 1;
end

%Display region boundaries
figure(1) ;
clf ; imagesc(I) ; hold on ; axis equal off; colormap gray ;

%Create contour plot using the values
%0:max(M(:))+.5 is the no of contour levels. Only level 0 is needed so 
%[0 0] is used.

[c,h]=contour(M,[0 0]) ;;
set(h,'color','r','linewidth',1) ;

%Retrieve the image data from the contour image
f = getframe;
I2 = f.cdata;

%Convert the image into binary; the red outlines are while while the rest
%is black.
I2 = all(bsxfun(@eq,I2,reshape([255 0 0],[1 1 3])),3);
I2 = imcrop(I2,[20 1 395 343]);

imshow(~I2);
like image 597
Zulway Avatar asked Nov 19 '14 10:11

Zulway


1 Answers

Proposed solution / trick and code

It seems you can work with M here. One trick that you can employ here would be to pad zeros all across the boundaries of the image M and then fill its holes. This would take care of filling the blobs that were touching the boundaries before, as now there won't be any blob touching the boundaries because of the zeros padding.

Thus, after you have M, you can add this code -

%// Get a binary version of M
M_bw = im2bw(M);

%// Pad zeros all across the grayscale image
padlen = 2; %// length of zeros padding
M_pad = padarray(M_bw,[padlen padlen],0);

%// Fill the holes
M_pad_filled = imfill(M_pad,'holes');

%// Get the background mask after the holes are gone
background_mask = ~M_pad_filled(padlen+1:end-padlen,padlen+1:end-padlen);

%// Overlay the background mask on the original image to show that you have
%// a working background mask for use
I(background_mask) = 0;
figure,imshow(I)

Results

Input image -

enter image description here

Foreground mask (this would be ~background_mask) -

enter image description here

Output image -

enter image description here

like image 178
Divakar Avatar answered Oct 11 '22 12:10

Divakar