0

I need to find the blobs from the below image.Spheroids The major problem is background. background doesn't have uniform intensity. I tried couple of things like thresholding and edge detection in MATLAB but couldn't able to find a better ways to segment out all spheroids. I need to extract the blobs and I need to find the area of each blobs. Does anyone know how to work-around with this kind of background?

Edit (07/02/17): As suggested by Spektre I tried Following things in MATLAB.

Method 1:

img_original = imread('~/my_image.jpg'); %Read image
img_ch = single(img_original(:,:,2));    %Pick one channel( here its green)

g = fspecial('gaussian',200,100);        %Kernel matrix to make the img blurr
con_img = conv2(img_ch,g,'same');        %2D convolution, this wil make the img blurr

sub_img = (con_img - img_ch);            %Simple matrix subtraction

sub_img(sub_img <= 10) = 0;              %Thresholding
sub_img(sub_img ~= 0) = 1;

fil_sub = imfill(sub_img,'holes');       %Fill the regions
imgfilt = imfilter(fil_sub, ones(3));    %run filter using 3by3 matrx
imgfilt(imgfilt < 8) = 0;                %Reduce noisy pixels by thresholding
mfilt_img = (medfilt2(imgfilt));         %reduce unwanted pixels

img = img_ch;
img(mfilt_img ~= 0) = 255;
img2 = img_ch;
img2(img2 < 70) = 0;                     %Threshold for darker pixels which are left out from above methode.
img(img2 ==0) = 255;
disp_img = img_original(:,:,1);
disp_img(img ==255) = 255;
img_original(:,:,1) = disp_img;
figure, imshow(img_original)

I got the segments but still not good enough I think. This method gave good segments in the high intensity background, Even if I reduce the threshold value segments are not clear in the darker background and brightest pixels in the blobs are excluded.

Method 2:

img_original = imread('~/cancer_cells/Snap-10234.jpg'); %Read image
img_ch = single(img_original(:,:,2));    %Pick one channel( here its green)
clear new_matcel cur_img matcel avg_matrx

s=3;                % Set size of the square window               
mat_img = img_ch;   % Working image channel
% resize the working matrix so that the dimensions matches
resize_img = resizem(mat_img,round(size(mat_img)/s)*s);

% convert matrix into small s x s matrix and save each in cells
window_c = ones(1,size(resize_img,1)/s) * s;
window_r = ones(1,size(resize_img,2)/s) * s;
mat_cel = mat2cell(resize_img,window_c,window_r);
new_matcel = cell(size(mat_cel));   % initialize new variable

% get the average value for each window and replace the actual by avg value
for i = 1:size(mat_cel,1)
    for j = 1:size(mat_cel,2)
        cur_img = mat_cel{i,j};
        avg_value = mean(mean(cur_img));
        new_matcel{i,j} = ones(s) * avg_value;
    end
end

avg_matrx = cell2mat(new_matcel);       % convert cells to matrix 

image_sub = (abs(resize_img - avg_matrx)); % take the absolute difference
image_sub(image_sub < 7) = 0;           % thresholding
image_sub(image_sub~=0) = 1;

image_sub = bwmorph(image_sub,'bridge');% fill gaps
image_sub = imfill(image_sub,'holes'); % fill the bounded regioons
% image_sub(image_sub == 1) = 255;
image_sub = resizem(image_sub,size(img_ch)); % resize to original size

disp_img = img_original(:,:,1);
disp_img(image_sub == 1) = 255;
img_original(:,:,1) = disp_img;
figure, imshow(img_original)

Much better segmented image:

img

even brighter pixels are included in the segment. Thanks to Spektre.

Is there a way to improve the above code? or any other idea to get more precise segments?

Thanks.

Spektre
  • 49,595
  • 11
  • 110
  • 380
AMS
  • 49
  • 1
  • 6
  • see [Enhancing dynamic range and normalizing illumination](http://stackoverflow.com/a/31558803/2521214) Also thresholding `intensity-sliding_average(intensity)` is a good start for this ... – Spektre Feb 04 '17 at 14:53
  • @Spektre Thanks for the suggestion. Intensity sliding average is some what similar to blurring right? If true, I have tried it. Did not work though :( – AMS Feb 05 '17 at 19:17
  • You blur the image ... then substract original image from it and threshold the abs of result. That will detect many points along the borders of each blob (similar to first derivation) from that you can use morphology operators to create ROI for whole blob area. This approach works (I tested it wen wrote that comment). – Spektre Feb 05 '17 at 20:23
  • there is also another option divide image to for example 8x8 squares and compute the max difference to average color in each square. Your blobs have cracks and the empty space is almost without change so squares with high difference have blob in it... – Spektre Feb 05 '17 at 20:25
  • @Spektre Thank you so much. I tried to implement both the methods. I think second one is bit different from the suggested idea. Please have a look at the edits, let me know if any improvements or changes required. – AMS Feb 07 '17 at 08:35
  • I do not use Matlab so I will not help with the code but you can now process all blobs and filter out too small ones or not circular or whatever you need (count of pixels is too far from circle area in respect to bounding box size, also aspect ratio of bounding box can tell you a lot). Take a look at [Fracture detection in hand using image proccessing](http://stackoverflow.com/a/37046721/2521214) bullet **#5** anyway the result looks good enough I think +1 for the results and effort from your side (now the question looks more as should). – Spektre Feb 07 '17 at 16:03
  • That already looks pretty nice. You can remove all the small dots by morphological opening, imopen(). If you wish to look at alternatives adaptive thresholding by adaptthresh() can do the segmentation pretty well. I've also got robust and easy results in similiar cases by levelling the background with [homomorphic filtering] (http://blogs.mathworks.com/steve/2013/06/25/homomorphic-filtering-part-1/) and automatic global thresholding via Otsu's method. – Tapio Feb 07 '17 at 16:56
  • @Spektre Thanks again for the edits and fracture detection link. I did filter out small patches and results are much better. – AMS Feb 08 '17 at 15:03
  • @Tapio Thank you for suggesting different methods, I have tried homomorphic filtering. results are pretty much similar. – AMS Feb 08 '17 at 15:07

0 Answers0