Color Analysis: identification of % blue color in the image

Hey there,

I have a photo of a mixture of blue plastic and sand (attached below). I want to identify the % area of the blue plastic (i.e. % blue color in the image) via imageJ. I’ve already tried the color pixel counter plugin, but my problem is with adapting the image before using the plugin.

Problem part 1:
I usually adjust the brightness/contrast and the color balance (set to blue) (under image > adjust ). However the % area of blue color changes with every slight change in the brightness/contrast and the color balance.

Problem part 2:
My aim is to split the image into grids (analyze > tools > grid) and then analyze each cell on the grid individually. Obviously I could not find an easy way to do that, so I hand-draw rectangles and then use the plugin to count the blue color pixel in every rectangle. The problem is that if the overall % blue in the image is 60%, then for each individual cell on the grid that I analyze, I will get a value that’s around 60%, even though I can easily tell that’s wrong by simple looking at the image.

*Note:
The reason I do not threshold is that once I do (color threshold), the plugin no longer recognizes the color blue (even if part of the image is still blue).

Thanks in advance,
R

Welcome @RALS93
maybe should should give k-means a try:

The result of k-means after a median 5x5 filter looks like that:

grafik

Hey,
Thanks for replying.
I’ll give your suggestion a try. Though I really want to try to work this out with the color pixel counter plugin.

Hello @RALS93
Please check if this macro responds to your request.
Please report your opinion to me.
Grettings

Grid-particules

Grid-particules

//-----------------

Image

Particules

//----------

Macro
macro "Particules"
{
requires("1.52v");
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
orig=getImageID();
setBatchMode(true);
//------------------------------
orig=getImageID();
run("Scale...", "x=0.5 y=0.5 width=764 height=764 interpolation=Bilinear average create");
run("Duplicate...", "copy");
close("\\Others");
rename("grid");
selectImage("grid");
//------------------------------------------------
run("Lab Stack");
run("Stack to Images");
close("a*");
close("L*");
close("a*");
selectWindow("b*");
setAutoThreshold("Huang");
//run("Threshold...");
setOption("BlackBackground", true);
run("Convert to Mask");
//--------------------------------------------
// Create grid
//------------------------
l=getWidth();
h=getHeight();
//setTool("rectangle");
n=0;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
selectImage("b*");
makeRectangle(i*(l/10),j*(h/10), l/10, h/10);
roiManager("Add");
run("Duplicate...", "title="+n);
n++;
}}
//--------------------------------
for(q=0;q<100;q++)
{
selectWindow(q);
run("Measure");
}
//----------------------------------
setBatchMode(false);
selectWindow("Results");
setLocation(0,0);
exit("All is done !");
}

Hi @Mathew,

Thanks for the macro. I tried it and got the results table with the numbers of the gird cells (1 - 100). However, once I ran the macro, the original image was gone and the only part that appeared was cell 99 (not the full image with the grid as shown in your post). Is there a way to fix this?

One other thing, the black background in the original photo is black because I cropped it out (it is actually glass that interferes with my analysis). Do you think I can exclude that part from the %area of the blue particles? Manually selecting the area before running the macro is no use. I am asking this because I have multiple images that I need to analyze and I crop out different parts from each. I also ran the macro using a different image (attached below, and also cropped out the glass) and got the exact same results as the first image … I looked at the macro code but I could not really generalize it to any image. Any suggestions?

Much appreciated!

Hi
@RALS93

The measurements take into account the periphery (black).
Change the 7th line by:
//setBatchMode(true);
The process will be slower.
Please report your results.
Greetings
PS:To see the image n ° 1 which I deposited it is necessary:
(Or make changes to the macro).
Reopen the original image
Apply reduction
apply roiManager show all

Hey @Mathew,

Thanks for replying :slight_smile: This is the closest I’ve gotten to what I am trying to achieve! I did as you suggested. The black surrounding is still being included in the analysis.

I played with the macro a bit:

macro “Particules”
{
//requires(“1.52v”);
//setBackgroundColor(0,0,0);
//setOption(“BlackBackground”,true);
//orig=getImageID();
//setBatchMode(true);
//------------------------------
orig=getImageID();
run(“Scale…”, “x=0.5 y=0.5 width=764 height=764 interpolation=Bilinear average create title=[image.jpg (red)-1]”);
run(“Duplicate…”, “copy”);
//close("\Others");
rename(“grid”);
selectImage(“grid”);
//------------------------------
//orig=getImageID()
run(“Split Channels”);
selectWindow(“grid (green)”);
close();
selectWindow(“grid (blue)”);
close();
selectWindow(“grid (red)”);
//makeOval(0, 0, 1508, 1518);
setAutoThreshold(“Default dark”);
//run(“Threshold…”);
setThreshold(0, 169);
run(“Make Binary”, “thresholded remaining black”);
//------------------------------
// Create grid
//------------------------
l=getWidth();
h=getHeight();
//setTool(“rectangle”);
n=0;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
selectImage(“grid (red)”);
makeRectangle(i*(l/10),j*(h/10), l/10, h/10);
roiManager(“Add”);
run(“Duplicate…”, “title=”+n);
n++;
}}
//--------------------------------
for(q=0;q<100;q++)
{
selectWindow(q);
run(“Measure”);
}
//----------------------------------
setBatchMode(false);
selectWindow(“Results”);
setLocation(0,0);
exit(“All is done !”);
}

*Note: the results are only for the grid cells; i.e. not the circular selection. Do you perhaps have a recommendation on how I can only get the area for the portion of the grid that is within the circular periphery (and hence exclude the outer area from the analysis)? I am asking because for profile images, the periphery is an irregular shape …

Thanks!