Identifying and counting closely spaced particles

The image file goes by the name of "dots" in the following.

This gives the basic layout of the components:

c = DeleteSmallComponents@ColorNegate[Binarize[dots, Method -> "MinimumError"]];
m = MorphologicalComponents[c] // Colorize 

colors

centroids = ComponentMeasurements[ m , "Centroid"];
radii = ComponentMeasurements[ m , "EquivalentDiskRadius"][[All, 2]];
componentLabels = (# /. {Rule[n_, b_] :> Text[n, b]}) & /@ centroids;
Graphics[componentLabels, Axes -> True, AxesOrigin -> {0, 0}]
points = componentLabels[[All, 2]];
areas = MapThread[Text, {Round@radii, points}];
Graphics[areas, Axes -> True, AxesOrigin -> {0, 0}]
estimates = ({Which[#[[1]] < 15, Blue, #[[1]] < 20, Red, True, Green],
        Point[#[[2]]]} & /@ areas) /. {Blue -> 
     Sequence[Blue, PointSize[.01]], 
    Red -> Sequence[Red, PointSize[.02]], 
    Green -> Sequence[Green, PointSize[0.03]]};
Graphics[{estimates}, Axes -> True, AxesOrigin -> {0, 0}]

This shows where the components lie:

components

The sizes of the components:

sizes

And the best guesses for singles (blue), pairs (red), and triples (green):

illust


Perhaps using ImageCorrelate can be useful. Lets call the original image img0. You can use the drawing tools (or whatever other method you would like) to grab a kernel. This is the one I chose:

ker = enter image description here

In my case, I obtained this kernel by simply using the Image Assistant and cropping out one of the spots from img0.

i = ImageCorrelate[img0, ker, NormalizedSquaredEuclideanDistance];

From here use MorphologicalComponents and ComponentMeasurements to grab the central coordinates.

dots = Point[#[[2]]] & /@ ComponentMeasurements[
    MorphologicalComponents[ColorNegate[Binarize[i, 0.22]]], 
    "Centroid"];

Here is the result

Show[img0, Graphics[{Yellow, dots}]]

enter image description here

It isn't perfect (is misses the triplet and has a "phantom" dot) but for very little tweaking it does a decent job.


I think you can do better in the binarization, which will make all subsequent tasks easier. I tried:

Manipulate[Binarize[img, t], {t, 0, 1}]

on your original image and found t=0.4 to be a good value. Calling this binarized image binImg you can get better segmentation using

MorphologicalComponents[ColorNegate[binImg]] // Colorize

enter image description here

This captures the triplet of closely spaced dots in the upper left as well as the two doubles in the bottom center. It may look as if the ones in the upper right have been lost, but they are just small (you can verify this by dilating the whole thing, when they become more apparent).