How to count number of small dots in a picture

2018-02-18 12:51:56

I have this picture of small particles in a polymer film. I want to count how many particles in the figure, so that I can have a rough estimation of the particle density. But the image quality is poor, I had a hard time to do it.


I have tried several ways to do it, but failed. below is the code.

The first method I tried is:


image = Import["Picture3.jpg"];

imag2 = Binarize[image, {0.0, 0.8}];

cells = SelectComponents[DeleteBorderComponents[imag2], "Count", -400];

circles = ComponentMeasurements[ImageMultiply[image,cells],"Centroid", "EquivalentDiskRadius"}][[All, 2]]; Show[image, Graphics[{Red, Thick, Circle @@ # & /@ circles}]]

Here is what I got:

So it does not count all the particle. Plus, it sometimes take several particle as one.

I read another method from a thread here, the code is:

obl[transit_Image] := (SelectComponents[



ChanVeseBinarize[#, "T

  • get the binarize image

    img = Import[""];

    binimg = LocalAdaptiveBinarize[img, 25];

    The effect like this:

    big = ImageDemosaic[binimg // ColorConvert[#, "Grayscale"] &,

    "RGGB"] // MinDetect // SelectComponents[#, "Count", # > 100 &] &;

    (array = WatershedComponents[GradientFilter[big, 2],

    DistanceTransform[big] // MaxDetect]) // Colorize

    Then your number is

    array // Max



    Use the Closing to optimize the binarize image.

    binimg = Closing[LocalAdaptiveBinarize[img, 25], 3]

    Then we get the array and verify the effect.

    (array = WatershedComponents[GradientFilter[binimg, 2],

    DistanceTransform[binimg // ColorNegate] //

    MaxDetect]) // Colorize

    Or you can like this:



    Point[(array /. 1164 -> 0 //

    ComponentMeasurements[#, "Centroid"] &)[[All, 2]]]}]]

    So the number of your component is:

    2018-02-18 13:14:19
  • You could try something like this


    ImageTake[img, {100, 400}, {100, 400}],


    ImageTake[img, {100, 400}, {100, 400}],






    for visualization and then



    ImageTake[img, {100, 400}, {100, 400}],





    to get an estimate of the numbers of particles. In any case I would start by selecting a subsection of the image where the lighting is as homogenous as possible. As you can see at the above example there's still a number of false positives and false negatives, and you'll also have to guesstimate the actual area your image is covering in order to calculate the density.

    2018-02-18 13:28:02
  • In the post referenced in the comment, the key ideas is

    In order to separate the overlapping cells, I extract a set of markers

    by finding local maximas of the DistanceTransform and use these as

    markers in WatershedComponents

    However exactly following that example verbatim won't work (because there are hyperparameters) and would give something like this:

    Here are the preprocessing steps I would take:

    s1 = GradientFilter[img, 5] // ImageAdjust;

    s2 = Threshold[s1, {"Hard", "Cluster"}];

    s3 = FillingTransform[s2];

    s4 = DeleteSmallComponents[s3, 30];

    The bottom line is that it is tough for a human to delineate the blobs, so it is for a computer. However you can play with the "minimum saliency" threshold as follows:

    marker = MaxDetect[DistanceTransform[s4, Padding -> 0] // ImageAdjust,



    w = WatershedComponents[GradientFilter[s4, 3], marker,

    Method -> {"MinimumSaliency", ms}];

    cells = SelectComponents[w, {"Area", "EquivalentDiskRadius"},

    10 <

    2018-02-18 13:34:26
  • The local binarization can help with the uneven lighting. Dilation helps disconnect some particles that remain connected, and DeleteSmallComponents removes small portions caused by noise.

    img = Import[""];

    comps = MorphologicalComponents[DeleteSmallComponents[

    ColorNegate[Dilation[LocalAdaptiveBinarize[img, 10], 1]]]];

    comps // Colorize



    2018-02-18 13:54:26