I have a bunch of Petri dishes full of dots which I'd like to count in Matlab. Can this be done reliably and in batches?
E.g. This plate has 352 colonies
I've tried ImageJ but need to do quite a bit of cropping out of the border and get variable results.
Do you have any suggestions?
Being kept in one place, the resulting cells have accumulated to form a visible patch. Most bacterial colonies appear white or a creamy yellow in colour, and are fairly circular in shape.
A colony counter is an instrument used to count colonies of bacteria or other microorganisms growing on an agar plate.
Most textbooks and lab manuals typically recommend using plates that yield somewhere between 30 and 300 colonies (or some similar range). Too few colonies, and the count may not be accurate; too many colonies, and it is difficult as well as time-consuming to distinguish the individual colonies on a plate.
My approach to this problem is as follows:
This file exchange toolbox provides us with a working circular Hough transform. Things are pretty straightforward from there:
function [count,colonies,bw] = colony_count(I)
I = rgb2gray(im2double(I)); %# Color-to-gray conversion.
[m,n] = size(I);
%# Uncomment this if you have might have some images with light background
%# and dark colonies. It will invert any that seem that way.
%#if graythresh(I) < 0.5
%# I = imcomplement(I);
%#end
bw = I > graythresh(I); %# Otsu's method.
radii = 115:1:130; %# Approx. size of plate, narrower range = faster.
h = circle_hough(bw,radii,'same','normalise'); %# Circular HT.
peaks = circle_houghpeaks(h, radii, 'npeaks', 10); %# Pick top 10 circles.
roi = true(m,n);
for peak = peaks
[x, y] = circlepoints(peak(3)); %# Points on the circle of this radius.
x = x + peak(1); %# Translate the circle appropriately.
y = y + peak(2);
roi = roi & poly2mask(x,y,m,n); %# Cumulative union of all circles.
end
%# Restrict segmentation to dish. The erosion is to make sure no dish pixels
%# are included in the segmentation.
bw = bw & bwmorph(roi,'erode');
%# Colonies are merged in the segmented image. Observing that colonies are
%# quite bright, we can find a single point per colony by as the regional
%# maxima (the brightest points in the image) which occur in the segmentation.
colonies = imregionalmax(I) & bw;
%# Component labeling with 4-connectivity to avoid merging adjacent colonies.
bwcc = bwconncomp(colonies,4);
count = bwcc.NumObjects;
We use this code like this:
I = imread('http://i.stack.imgur.com/TiLS3.jpg');
[count,colonies,mask] = colony_count(I);
I have also uploaded the colony_count
function on the file exchange. If you have an image which doesn't work but you think should, leave a comment there.
The count is 359, which I'd say is pretty close. You can inspect the segmentation (mask
) and colony markers (colonies
) to see where mistakes are made:
%# Leave out the changes to mask to just see the colony markers.
%# Then you can see why we are getting some false colonies.
R = I; R(mask) = 255; R(colonies) = 0;
G = I; G(mask) = 0; G(colonies) = 255;
B = I; B(mask) = 0; B(colonies) = 0;
RGB = cat(3,R,G,B);
imshow(RGB);
You could use a technique called connected component labeling which can be used do distinguish between different objects in an image.
First of all you need to make the image binary by some mean of thresholding. The labeling is the done by scanning each pixel row twice, once left-to-right and once right-to-left. We are looking for object pixels, i.e. pixels that have value 1.
In the left-to-right scan: for each pixel p: If p is an object pixel, copy the label from above or left. If p is a background pixel or p has a label, do nothing.
For the right-to-left scan: for each pixel p: If p is an object pixel, copy the label from the right if there is one, otherwise set a new label. If p is a background pixel or p has a label, do nothing. If a label exists and the pixel to the right of p has a different label, make a note of this.
For example (from lecture slides at http://webstaff.itn.liu.se/~bjogu/TNM087-2012/Fo7-2012-AH.pdf):
When you have scanned the whole image, merge all labels that you have noted (they are connected to the same object) and then count the number of distinct labels and you will have your count.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With