# Estimating colored areas on an image

I have an image of a figure:

I want to estimate the areas of colored regions separately. If data are available, then one could apply Integrate[Interpolation[**data**, {x-range}]. Unfortunately, actual data are not available, although the figure itself is.

There are some examples in this SE, playing with images to extract the underlying data such as Filter a specific area of an image.

Any idea?

• Try ComponentMeasurements[image // Binarize, "Area"] but you will probably need to tinker with the Binarize to get good segmentation of the regions. I played around a bit and it may be necessary to just use a single bit plane (ImageData) since the regions may not be all the same pixel values but shaded. Jan 9 at 23:08
• @OpticsMan: I run your code and got a bunch of numbers. I do not know what they represent. Some numbers are way beyond the possible range. Basically, it is very hard to make sense of the numbers. Do you know what the output refers to? Jan 9 at 23:41

## 2 Answers

It is also worth using the Mathematica functions

DominantColors[gr, 3, {"Color", "Coverage","CoverageImage"}, "Dataset", MinColorDistance -> 0 ]


Result agrees well with RolandF's answer!

• Good estimation, too! Very short one line. I have the same comment as the one I gave to other answer. Why does it not total to 100%? Perhaps, the the colored lines between different regions are excluded from the calculation. Jan 10 at 15:21
• In the figure, I deliberately give the X-Y axes with numbers. Is there any way to use the X-Y axes to extract the data in the form of {(X, Y)} for the gray area and similarly for the curve associated with the green color, and the rest will be light brown. Jan 10 at 15:41
• @TugrulTemel That means you are looking for a "digitizer"? Perhaps this link Recovering data points from an image helps Jan 10 at 16:00

There is no better implementation than just to count raster points of colors.

Paste your graphics into a variable

Get image raster data and delete possible alpha channel.

   gr1 = Map[(Take[#, 3] &), ImageData[ gr ], {2}];


Define a select function for RGB below a white treshhold (or distances to any other uniform background colors) for a whole row of the raster

   sel = (Select[#, ( Mean[Flatten[#]] < 0.98 &)] &);


and select colored rows and columns.

   gr2 = sel[ sel[gr1]\[Transpose]]\[Transpose];


Optical check of cropped result

  Image[Raster[gr2]]


   total = Times @@ Dimensions[gr2][[1 ;; 2]];


Map count function into logic of the three predominant colors

 (PercentForm[
N[Count[ gr2, {R_Real, G_, B_} /; #, {2}] / tot]] &) /@
{R > G && R > B, (G > R && G > B), (B > R && B > G)}

{25.95%, 50.3%, 23.05%}

• Good estimation! I think in the last step of your code, tot should be total. Other than that, I wonder why the percent distribution is not totaling to 1. Will that make sense if I Normalize[**%distribution**, Total] because any image in its totality should be equal to 100%. The %distribution in the image given in the question is almost equal to 100%. But when I try it with different images, I get less than 100% distribution of the three colors. Jan 10 at 15:18
• I roughly used < conditions only. In a discrete lattice, the partitions have to include <= cases, but with more than two colors , to count differently colored boundaries doesn't make much sense. Rests of white points on the outer edges are left out, too. The best way is to count the points over all three colors, or, more simple, divide by the sum of percentages to norm it to 100% Jan 11 at 17:09
• Thanks for your clarification. Jan 11 at 17:33