Counting areas with diferent colors


#1

Continuing the discussion from Classifying by color and shape:

Hello there! I need to separate and count the areas with different colors in the image below. Is there anybody who could tell me how to do this? and also how to do a macro to analyse several images? I’m new imageJ user , so, any information would be useful to me.
Thank you very much!


#2

Hi JuanJimenez

If you want to create a macro you can use in Plugins >> Macros >> Record… It records your actions and it generates a macro which you can execute.

To the image:

One way is to find edges (Process >> Find Edges). There are edges in your image if there are adjacent pixels with a high difference. In this case we get the outlines of the areas

Based on that you have to invert the image (edit >> Invert) for further analysis

Now all areas are white and the borders are black. Based on that we can do a connected component analysis We can do it with find connected regions (Plugins >> Process >> Find Connected Regions)

Greetz
JohM3i


#3

Hi @JohM3i, Thank you very much for replying. I have done the process you suggested but there is not a clear outcome to me. I am attaching another picture that is better than my previous pic was. So, I intend to measure the area of both the green leaves and red leaves. If you have another comments it will be appreciated.
Regards,

Juan


#4

Hello @JuanJimenez,

If your image is already labeled, i.e. each region has a different value (not RGB), you can use the geometric measurement tools available in MorphoLibJ to obtain the area or volume of each individual label.

Cheers!

ignacio


Closing Circle Edges
#5

hi @iarganda, thank you very much for your suggestion.
I’m sorry but my experience in programming is poor, what do you meant with “labeled”?, how I can label my image? I ran Plugins>>MorphoLibJ>>Analyze>>Region Morphometry and I got a table with several areas instead of two ares (red and green leaves) as I expected.
Thank you very much for your support.

Regards,
Juan


Set fixed Threshold in Macro
#6

By “labeling” he means that each area of your images have a single unique pixel value (typically starting at 0 or 1 and then incrementing), rather than a range of values. Downloading the PNG you posted, I see that this is indeed the case.

One simple way to get the count of each area is:

  • Analyze :arrow_forward: Histogram
  • Click the List button

Then you will see a table of values, mostly zeroes, but the first few values will have pixel counts.

If you need to separate the areas into individual masks, you can use repeated thresholding (shift+T) followed by Edit :arrow_forward: Selection :arrow_forward: Create Mask. Or here is a macro I whipped up for splitting labelings into individual masks:

id = getImageID();
title = getTitle();
getHistogram(values, counts, 256);
for (i=0; i<256; i++) {
	if (counts[i] > 0) {
		setThreshold(values[i], values[i]);
		run("Create Mask");
		rename(title + "-" + values[i]);
		selectImage(id);
	}
}
resetThreshold();

#7

can anyone show step by step how to make lable since i have the same problem…


#8


#9

Hello @khairul,

You have to first convert your image to black and white (usually by applying a threshold) so your regions of interest are white and the background is black. Then you can use any of the available connected components tools to label each of those regions with a different label. In MorphoLibJ, you can use the plugin under the menu Plugins :arrow_forward: MorphoLibJ :arrow_forward: Binary Images :arrow_forward: Connected Components Labeling.


#10

Hi @ctrueden and @iarganda,

Thank you very much indeed! Both macro and geometric measurement tools works well with the previous picture I posted. However, I have some doubts with my first image posted. I have cut my original image in order to avoid noise (see edges in the picture).

After cutting I obtained this picture:

Using the MorphoLibJ plugin with the original picture I obtained a lot data:

and using the cut image I obtained just two values

I suppose it refers to black and gray colors in the picture. I need to analyse (counting the areas with different color) more than 200 pictures, therefore, I would like to fully understand this process before proceeding to analyse.

Regards,

Juan


#11

Hai iarganda,

my purpose is to calculate yellow region fraction. when i convert my image to black and white using threshold the yellow region become white.


#12

Hello @JuanJimenez ,

It looks like you made a conversion of the pixel type when you cut your image. Make sure you have the same number of labels before and after. You can check them by looking at its histogram (CTRL+H or Analyze :arrow_forward: Histogram).


#13

Hello @khairul,

Yes, you need to convert your yellow areas to white and the rest to black, then use the connected components tool as I mentioned on my previous post.

ignacio


#14

Hey @iarganda, I have checked my files and I figured out that the difference was because the original picture was .jpg and the cut image was .png. Now, I changed the original picture to .png and it is working well!
Thanks!!

Juan


#15

Hello @iarganda, I have another question to you (I’m sorry). I’m using the Trainable Weka Segmentation to analyse my images. Is there any way to speed up the process? I have made my classifier and I need to apply it to set of 200 images, I have tried with a subset of 5 images and it took a lot of time. Likewise, I’m having issues with the .png format. I was trying to apply my classifier to my subset of pictures, however, in the disk (where the program ask to save the segmented images) I obtained one segmented picture instead of 5. Is there any trouble with .png format?
Thank you very much!

Juan


#16

Dear @ctrueden, I have been successfully using the code you shared, however, I would like to run this process in a set of images using a macro. I have written some lines, please see my code below.

Input=getDirectory("Choose Direction File");
Outcome=getDirectory("Choose Output File");

macro "segmentation" {

  Images=getFileList(Input);

  for (j=0; j<Images.length; j++){
    open(Input + Images[j]);

    setBatchMode(true);

    id = getImageID();
    title = getTitle();

    getHistogram(values, counts, 256);
    for (i=0; i<256; i++) {
      if (counts[i] > 0) {
        setThreshold(values[i], values[i]);
        run("Create Mask");
        rename(title + "-" + values[i]);
        selectImage(id);
      }
    }
    resetThreshold();

    selectImage(values[1]);
    saveAs("PNG", Outcome + title + "_Green" + ".png");

    selectImage(values[2]);
    saveAs("PNG", Outcome + title + "_Dead" + ".png");


    run("Set Measurements...", "area center perimeter area_fraction redirect=None decimal=3");
    run("Measure");
  }
}

When I run it, only the first image in my input folder was read. I need to create a newArray? since the outcome of the threshold process are three pictures? How can I do that?
thank you very much in advance!
Juan


#17

Hello again @JuanJimenez,

Regarding the speed, it really depends on how many processors you have, the size of your images and the number of features you’re using.

PNG is fine for a single image, but for a stack you need a format that can be saved as multi-images such as TIFF.

I hope this helps!


#18

Hi @iarganda, thank you very much for replying! I really appreciate your help!
Regards,

Juan


#19

Dear @iarganda, I guess my pictures are too big, those are 32 bits, 4224 x 3168 . Is there any way in ImageJ to reduce the size of the picture without reducing its quality? I have done a segmentation with a .tiff image using my classifier but it does not work.
Thank you very much,

Juan


#20

I see. You have at least two options:

  1. Train on reduced versions of your images (you can resample them using Image :arrow_forward: Scale).

  2. Train on cropped versions of your input images but testing on the full size version.