Measuring spaces in jpeg

I want to measure the amount of jpeg that is white / yellow (within a tolerance that can be adjusted).

I am trying to develop a quality control tool that measures defects in almonds. Defects are scratches on the skin of brown almonds (see image below). Since these defects are white / yellow, I would like to just load the image in R and measure the amount of white in the image. Then I can experimentally determine the acceptable level. All images will be the same size.

Almond picture

+3


source to share


3 answers


Carl post is 99% of the answer, here's a bit more to get the measurement of the amount of the image white / almost white:

# Required package
library(jpeg)

# Load and plot data
jpg <- "C:\\my_image.jpg"
my_jpg <- readJPEG(jpg)

# or for stand-alone reproducibility: 
# my_jpg <- readJPEG(system.file("img", "Rlogo.jpg", package="jpeg"))

# have a look at the original image
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(my_jpg,0,0,1,1)
# prints the jpg, just to make sure it gone in ok

      

enter image description here



# Following Carl example, subset each channel to get
# the pixels with white values (ie. close to 1) and make
# non-white pixels black for convienence. As Carl says,
# you'll need to adjust the values from 0.99 for your
# use case 
white_red_channel <- ifelse(my_jpg[,,1] > 0.99, 1,0)
white_green_channel <- ifelse(my_jpg[,,2] > 0.99, 1,0)
white_blue_channel <- ifelse(my_jpg[,,3] > 0.99, 1,0)
# combine channels into array
white <- simplify2array(list(white_red_channel, 
                             white_green_channel, 
                             white_blue_channel))

# plot white/near-white pixels only
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(white, 0, 0, 1, 1)
# looks pretty good, whiter areas on original are highlighted here:

      

enter image description here

# find proportion of image that is not black
whites <- white_red_channel + white_green_channel + white_blue_channel # sum channels
not_black <- sum(whites > 0) # count pixels that are not black
total_pixels <- ncol(whites) * nrow(whites) # find total number of pixels
not_black / total_pixels # proportion of non-black pixels
[1] 0.01390833

      

+4


source


It would be easier to rasterize as BondedDust suggested, but whatever you want is to define the range of colors (RGB or otherwise) that qualifies as a defect.
Consider:

library(jpeg)
foo <- readJPEG('foo.jpeg')  #returns a NxMx3 array

# find qualifiers in each layer for lmit values you chose
badred <-which(foo[,,1] > redlimit, arr.ind=TRUE)
badgreen <-which(foo[,,2] > greenlimit, arr.ind=TRUE)
badblue <-which(foo[,,3] > bluelimit, arr.ind=TRUE)

      



This gives you three matrices filled with column pairs of rows, columns. Find the pairs that match (there is some quick way to do this, but naturally I forgot how it is now :-() Or you can plot all three matrices and observe the areas of overlap:

plot(badred[,1],badred[,2],pch=19,cex=.5,col='red')
points(badgreen[,1],badgreen[,2],pch=19,cex=.5,col='green')
points(badblue[,1],badblue[,2],pch=19,cex=.5,col='blue')

      

+3


source


I suggest a different approach. Work in YCbCR color space. The Y-Channel is B&W White. If you are only looking for whiteness, you can only find this in the Y-Channel.

High Y values ​​= white. Low Y-values ​​= black.

I am guessing that some clipping (anything above 200) indicates whiteness.

+1


source







All Articles