Search code examples
matlabimage-processingmatlab-figure

how to segment the colony When I can't use bw image


I tried to use image processing toolbox to count my colony. I used imfindcircles to find the colony and count. But I got some problems:

(1)Due to that my colony could be white and black, I tried to find the colony by using Bright or Dark in ObjectPolarity, and use a if loop to select which one I finally choose. But the first step of my if loop doesn't really work.

(2) For using imfindcircles to find the circle, I found it works for the colony in white, while the method is a disaster for the black colony. I'm kind of desperate now because I can't find other ways to segment the colony.

So finally i need to: label each colony in the plate, count the colony number, calculate each colony size, extract the mean gray value for each colony (the colour).

Thank you very much!!!

So here is my code:

im = imread(test.jpeg)
imshow(im)
% to find the colony
[centersBright, radiiBright] = imfindcircles(im,[30 60],'ObjectPolarity','bright','Sensitivity',0.925,'Method','twostage','EdgeThreshold',0.1)
[centersDark, radiiDark] = imfindcircles(im,[30 60],'ObjectPolarity','dark','Sensitivity',0.925,'Method','twostage','EdgeThreshold',0.15)
% to select which one is the correct count. if one of the length(centres) value is lower than 10, I consider it as an error. But if both length(centres) is low than 10, I consider it as a treatment effect and accept the value.
if length(centersDark)<10<length(centersBright)
centers=centersBright
radii=radiiBright
elseif length(centersBright)<10<length(centersDark)
centers=centersDark
radii=radiiDark
else
centers=[centersBright,centersDark]
radii=[radiiBright,radiiDark]
end
% view and label the colony
h = viscircles(centers,radii)
for k = 1:length(radii)
string = sprintf('%d',k)
text(centers(k,1),centers(k,2),string,'color','y','HorizontalAlignment', 'center','VerticalAlignment', 'middle')
area(k)=pi*radii(k)^2
end

Sample image


Solution

  • Suggested Solution

    While it's hard to distinguish between the colonies and their surrounding in the black and white version of your input, it is not hard to do so in the hue space by using thresholding. The reason is that the colonies have a unique hue which is different from their background. This will be more noticable after converting to HSV space:

    enter image description here Therefore, I suggest the folowing solution:

    1. convert input image to HSV space
    2. use thresholding on the hue component.
    3. extract connected components
    4. Use the connected components which are large enough for the mask
    5. perform imclose opertation for cleaning the artifacts

    Code

    %reads the image
    I = imread('colony2.png');
    %convert to hsv
    hsvIm = rgb2hsv(I);
    %thresholding on the hue space
    bwIm = hsvIm(:,:,1) < 0.15;
    %find connected components
    CC = bwconncomp(bwIm);
    %choose only cc with sufficient amount of pixels
    numPixels = cellfun(@numel,CC.PixelIdxList);
    relevantCC = CC.PixelIdxList(numPixels > 10);
    %generate a binary mask with these conencted componants
    colonyMask = false(size(bwIm));
    for ii=1:length(relevantCC)
        colonyMask(relevantCC{ii}) = true;
    end
    %perform morpholopical operations for cleaning
    colonyMask = imclose(colonyMask,strel('disk',1));
    
    %display result
    h = imshow(I); % Save the handle; we'll need it later
    set(h, 'AlphaData', ~colonyMask);
    

    Results

    enter image description here

    Selection of threshold

    The threshold was chosen by choosing the first pick in the histogram of the hue component

    histogram(hsvIm(:,:,1))
    

    enter image description here