First, I renamed the image that you gave me. It is now named asikaga.jpg I have removed the sale from the image for it is a distraction when we count the pixels with one color or another.

Also, you need to take photographs with a neutral background, so that if you have white sand or gravels, you don’t want to get the photographs taken with a white background, you want to have something with a blue background or any color you are not using.

What we do first is to load the packages that we need in R. The first time you will use them, you will need to install the packages with the function install.packages(“the name of the package here”). You may need to download other subpackages, but this is not difficult.

/ install.packages(“colordistance”) install.packages(“countcolors”) install.packages(“jpeg”) /

First, we set our work directory, i.e. where the files you are working with are located. For me, it is on my desktop. Please note that YOUR PATHWAY WILL BE DIFFERENT. Then we load the different libraries.

setwd("C:/Users/kaiki/Desktop")  # set the working directory
library(colordistance)
## Warning: package 'colordistance' was built under R version 4.0.3

Now, there is another step that you can do in ImageJ or using R, and this is to find the values of the different colors. On your image, you have green grains and red grains (the white grains will not be visible on this image, you need to retake the photograph with a blue or any other color background).

I have made small screenshots of the parts of the image showing either the green color or the red color, so that I will use the information from those small images to define what is Red and what is Green.

red <- jpeg::readJPEG("red.jpg")
green <- jpeg::readJPEG("green.jpg")

Then we define what is meant by red or green by plotting the histograms

par(mfrow=c(2,3)) # divides the graphic zone in 2 columns
hist(red[,,1])
hist(red[,,2])
hist(red[,,3])
hist(green[,,1])
hist(green[,,2])
hist(green[,,3])

You can see from the graph above, that the range of values is different for the 3 bands Red, Blue Green for both colors Red and Green. We can use this data to thus differentiate the two colors on an image.

As we want numerical values, we are gonig to extract them from the histograms as follows (I am only giving you an example for the green image, you need to also do it for red)

R<-hist(green[,,1]);

G<-hist(green[,,2]);

B<-hist(green[,,3]);

R
## $breaks
##  [1] 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40
## [16] 0.42 0.44
## 
## $counts
##  [1]   8  49 137 364 576 958 635 342 103  31  13   9   9   3   6   5
## 
## $density
##  [1]  0.12315271  0.75431034  2.10899015  5.60344828  8.86699507 14.74753695
##  [7]  9.77524631  5.26477833  1.58559113  0.47721675  0.20012315  0.13854680
## [13]  0.13854680  0.04618227  0.09236453  0.07697044
## 
## $mids
##  [1] 0.13 0.15 0.17 0.19 0.21 0.23 0.25 0.27 0.29 0.31 0.33 0.35 0.37 0.39 0.41
## [16] 0.43
## 
## $xname
## [1] "green[, , 1]"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"
G
## $breaks
##  [1] 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50
## [16] 0.52 0.54
## 
## $counts
##  [1]   3  53  98 242 583 870 834 366 141  21  13   6   6   4   5   3
## 
## $density
##  [1]  0.04618227  0.81588670  1.50862069  3.72536946  8.97475369 13.39285714
##  [7] 12.83866995  5.63423645  2.17056650  0.32327586  0.20012315  0.09236453
## [13]  0.09236453  0.06157635  0.07697044  0.04618227
## 
## $mids
##  [1] 0.23 0.25 0.27 0.29 0.31 0.33 0.35 0.37 0.39 0.41 0.43 0.45 0.47 0.49 0.51
## [16] 0.53
## 
## $xname
## [1] "green[, , 2]"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"
B
## $breaks
##  [1] 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40
## [16] 0.42
## 
## $counts
##  [1]   1  52 112 455 795 961 569 152 100  16  12   8   4   6   5
## 
## $density
##  [1]  0.01539409  0.80049261  1.72413793  7.00431034 12.23830049 14.79371921
##  [7]  8.75923645  2.33990148  1.53940887  0.24630542  0.18472906  0.12315271
## [13]  0.06157635  0.09236453  0.07697044
## 
## $mids
##  [1] 0.13 0.15 0.17 0.19 0.21 0.23 0.25 0.27 0.29 0.31 0.33 0.35 0.37 0.39 0.41
## 
## $xname
## [1] "green[, , 3]"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"

From the result in the R console, the R tells us which bin of the histogram is most representative and what value it is centred on. Here we choose to have R=0.23 G=0.33 and B=0.23 as it is the mode value of the green color.

center.spherical <- c(0.23, 0.33, 0.23) #central values
lower.rectangular <- c(0.18, 0.28, 0.2) # limit
upper.rectangular <- c(0.31, 0.45, 0.3) #limit
# read the image to analyze

asika <- jpeg::readJPEG("asikaga.jpg") 


# use the libary countcolors

library(countcolors)
## Warning: package 'countcolors' was built under R version 4.0.3
# using the center.spherical values defined above we do a "circle search" around the value for all similar colors, and we do it with a radius of 15% (0.15 in the formula)

asika.spherical <-sphericalRange(asika, center = center.spherical, radius = 0.15, color.pixels = FALSE, plotting = FALSE)

# finally, this function gives you the fraction of Green colors on the image. BE CAREFUL as this value includes the white background. You will need to redo that for that red colors, and then use the Red + Green as 100% to remove the white background.

asika.spherical$img.fraction
## [1] 0.4998882

Then you can have a look at how it looks like on your image, using a dummy color over your data:

par(mfrow=c(1,1))
changePixelColor(asika, asika.spherical$pixel.idx, target.color="green")