Counts dots number and intensity in a sophisticated background



Hi, I am counting number of spots and quantify its pigmentation intensity. There are many methods available online to count the spots in a very clean background, not like the one i am having. I splitted the image into different channels, then try to capture them, but the result is not really ideal, the algorithm missed a lot of them. please see the one attached, both original and the processed. any advices will be greatly appreciated.


Good day,

the problem is not only the background but also that the dots are not homogeneous. They have a structure.

I’d try the magenta-channel after RGB->CMYK conversion, subtract background with appropriate parameters and some Gauss smoothing. Finally do the thresholding by an automatic scheme.
16bit images, i.e. images with better value range than 8bit per color channel, will help!

Here is the result of a first attempt:

I’m sure this approach will not generalize to other images of this type of plant.

Please tell us how you acquire the images: Illumination, Camera, Optics, etc.

In any case, please post a typical raw image in the original TIF- or PNG-format. No JPG-format though, because JPG introduces artifacts! You may also post images as Zip-archives.
(Converting a JPG-compressed image to TIFF- or PNG-format doesn’t make sense.)




Thank you Herbie for your quick response.

I am using an EPSON scanner/printer to acquire the image, not exactly sure the bits of the image. after scanning, it automatically saved as jpeg, i should have saved it as tiff if it will make a difference.

When I split the channel, it automatically says 8 bits in imagej.

The dots are a little stretched not because of the scan, but more related to flower growth, which is another problem as not a single spot is the same with any other spots.


Good day!

Because I don’t know exactly which EPSON-apparatus you are using, I can’t claim that it can deliver 16bit per color channel images but I’m pretty sure it does. Please study the scanner manual.

In any case, no JPG-compressed images for scientific work!
As mentioned before, JPG introduces artifacts that can’t be removed. These artifacts lead to additional problems with image evaluation.

Did you try RGB->CMYK conversion?

What is your impression of my first attempt to binarize the image?
Do you judge it better than what you’ve achieved before?

Two important questions:

  1. There are dots on the yellow part but also on both sides of it.
    Are you interested in both or only in those on the yellow part?
  2. Concerrning the structure of the dots.
    If you want to count the dots, we need to know exactly what you call a dot. What appears as a dot at first sight may indeed be two or more dots. So please formally define what you regard as a single dot. (We need formal definitions because this is the only language that computers understand.)




Hi, Herbie
Thank you so much for your help !

You first attempt looks way better than mine ! I have not figured out the RGB->CMYK conversion yet. My comment is that the pink petals seems to be a problem in counting, the automation process picks up too many from those regions. Someone suggests making a mask for just counting the spots within the boundary of yellow colors, it is not ideal, but I think it is a reasonable solution, least the petals, the edges in your binary image should be gone. I am not sure, I am still trying to work out how exactly to perform the masking.

TO responses to your two questions.
1 I am interested in capture as many spots as possible, like I said above, I would be happy if I just count the spots within the yellow region, as the spots outside of it seems negligible.

2 the dot that I define is the solid patch of pigmented cells (without holes in it), regardless of shape, can be stretched, round, or whatever forms. hope this helps clarify.


okay, here is what I did with the mask, but it seems improved a bit compared to yours, maybe? But I still get the mask work 100% well, as you can see there are still edges that should not have been there, before merging with the image to be counted. sorry for some reasons, it does not allow me to upload the masked image that is ready to be counted.


Good day!

Thanks for the details!

Today I did some experiments with a mask that was derived from the yellow part. It works quite well.

Here is a first binarized result obtained with some pre- and post-processing:

Please note that it may perhaps be possible to reduce or eliminate the rather broad boundaries.
(I shall try tomorrow.)

Stay tuned



This looks very cool, here is the one I did, it is still not ideal, hope you can point a direction, what functions that I can play with to work out the broad boundaries. I have used filter->gaussian smooth, i subtrate background, so far.


Good day,

here is an ImageJ macro code that results in a certain compromise between splitted spots and missed spots for the provided sample image:

Updated 13. Oct. 2018:

// imagej-macro "spotPreparation" (Herbie G., 12./13. Oct. 2018)
requires( "1.52g" );
if ( List.get("RGB to CMYK")=="") {
   showMessage("Required Plugin", "<html><h3>Macro requires ImageJ-PlugIn \"RGB to CMYK\"!</h3>"
     +"<a href=\"\">Download</a>"); exit();
if (nImages>0) { showMessage("Warning", "All images will be closed now!"); close("*"); }
setOption("BlackBackground", true);
run("RGB to CMYK");
run("Stack to Images");
run("Gaussian Blur...", "sigma=10");
setAutoThreshold("IJ_IsoData dark no-reset");
run("Convert to Mask");
run("Fill Holes");
run("Enlarge...", "enlarge=-16");
run("Restore Selection");
md = List.getValue("Median");
run("Make Inverse");
run("Set...", "value=&md");
run("Select None");
run("Rotate 90 Degrees Left");
run("Gaussian Blur...", "sigma=4");
run("Bandpass Filter...", "filter_large=70 filter_small=0 suppress=None tolerance=0");
run("Duplicate...", " ");
setAutoThreshold("Yen dark no-reset");
run("Convert to Mask");
run("Fill Holes");
run("Analyze Particles...", "add");
roiManager("Show All without labels");
run("From ROI Manager");
run("Overlay Options...", "stroke=green width=1 fill=none apply");
showMessage(""+roiManager("count")+" spots were found.");
close("ROI Manager");
function setWand() {
   x = List.getValue("XM");
   y = List.getValue("YM");
   while (getPixel(x, y)<255) { x++; y++; }
   doWand(x, y);
// imagej-macro "spotPreparation" (Herbie G., 12./13. Oct. 2018)

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

174 spots are found.
As you can see, there are quite some splitted spots and quite a number of unrecognized ones. However, this is the best result I could get so far.




Looks great! This is probably as good as it can get. How to acknowledge you if I am to put this in a manuscript in future?

Thank you so much for your help!




as I’ve written, the approach is a compromise and the results will depend on the image quality and the specimen as well. I have no idea how the parameter setting that i used for the macro will generalize to other images.

In the first place you should have a look at the numerical values in:

run("Enlarge...", "enlarge=-16");
run("Gaussian Blur...", "sigma=4");
run("Bandpass Filter...", "filter_large=70 filter_small=0 suppress=None tolerance=0")

Never use a hand-set threshold, always use one of the automatic schemes:

setAutoThreshold("Yen dark no-reset");

Schemes “Yen” and “RenyiEntropy” lead to the same result for the provided sample image but this need not be the case for other images.

As you may have realized already, the “Bandpass Filter”-operation is time consuming but leads to much better results than the “Subtract Background…”-operation.

How to acknowledge you if I am to put this in a manuscript in future?

Either you put a remark in a footnote or for publications add a last section before the references which should be named “Acknowledgements” in which you tell the reader about help you’ve received etc.
(Click on my name to get some personal details.)

Good luck



Thank you, Herbie. Though this took a bit longer, it did a very good job. I guess we would never reach the precision level as counting them one by one personally. But I think it is a reasonable compromise.

To follow up this question further, if I am to quantify the ratio of the the summed area of all spots over the entire yellow area. What is the best way to do it? Is it “simply” a task of counting the number of pixels for each defined area? How about the intensity? If spots intensity are also to be quantified, how to approach this, add a standard color checker right next to the flower that i need to quantify? It is really daunting to think all of these. I am about to scan a fresh flower with a standard color checker right next it and save it as tiff. Does this sound a good start?

Again, I really appreciate your help!



Good day Baoqing!

To follow up this question further, if I am to quantify the ratio of the the summed area of all spots over the entire yellow area. What is the best way to do it?

You have to decide.

I don’ think that with the pre-processing for counting you will get reasonable results for the quantification. Your image data is not suited for such evaluation.
Think of the top area where the contrast is so low that not even the counting is possible. How do you think you could do selective intensity measurements?

I see no sense in using a color checker.

The only approach to get what you are heading to is better image acquisition. I’ve mentioned this before:
Even illumination and perhaps colored light to increase the contrast, 16 bit images and no JPG-compression. The latter already plays a role when evaluating the top area.

I think it is time that you start doing what has been proposed and to learn using ImageJ in a professional way which includes understanding and writing macros.

Good luck