Source: https://cran.r-project.org/web/packages/imager/vignettes/gettingstarted.html

library(imager)
## Warning: package 'imager' was built under R version 4.0.3
## Loading required package: magrittr
## 
## Attaching package: 'imager'
## The following object is masked from 'package:magrittr':
## 
##     add
## The following objects are masked from 'package:stats':
## 
##     convolve, spectrum
## The following object is masked from 'package:graphics':
## 
##     frame
## The following object is masked from 'package:base':
## 
##     save.image
filePath <- system.file('extdata/parrots.png', package = 'imager')
im = load.image(filePath)
plot(im)

class(im)
## [1] "cimg"         "imager_array" "numeric"
im
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 3
class(im/2)
## [1] "cimg"         "imager_array" "numeric"
im
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 3
grayscale(im)
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 1
dim(im)
## [1] 768 512   1   3
grayscale(im)
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 1
dim(im/2)
## [1] 768 512   1   3
# Just example of formula
log(im)
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 3
10*sqrt(im) - log2(im)
## Image. Width: 768 pix Height: 512 pix Depth: 1 Colour channels: 3
#mean(im)
#sd(im)

#mean(im/2)
#sd(im/2)

mean(im) - mean(boats)
## [1] -0.1075309
mean(im/2) - mean(boats/2)
## [1] -0.05376544
sd(im) - sd(boats)
## [1] 0.08032755
sd(im/2) - sd(boats/2)
## [1] 0.04016378

Compare

layout(t(1:2))
plot(im)
plot(boats)

# They look the same!!!
# Plot rescales

Compare again

layout(t(1:2))
plot(im,rescale=FALSE)
plot(boats, rescale=FALSE)

plot(boats/2, rescale=FALSE)
plot(im/2,rescale=FALSE)

Histograms

grayscale(boats) %>% hist(main="Luminance values in boats picture")

grayscale(im) %>% hist(main="Luminance values in parrots(im) picture")

grayscale(boats/2) %>% hist(main= "luminace values in boats/2 picture")

grayscale(im/2) %>% hist(main= "luminace values in parrots(im/2) picture")

R(boats) %>% hist(main="Red channel values in boats picture")

R(im) %>% hist(main="Red channel values in parrots(im) picture")

R(boats/2) %>% hist(main="Red channel values in boats/2 picture")

R(im/2) %>% hist(main="Red channel values in parrots(im/2) picture")

Image –> Data Frame

library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
bdf <- as.data.frame(im)

# view all channels
head(bdf,3)
##   x y cc     value
## 1 1 1  1 0.4549020
## 2 2 1  1 0.4588235
## 3 3 1  1 0.4705882
# separate channels
bdf <- mutate(bdf,channel=factor(cc,labels=c('R','G','B')))
ggplot(bdf,aes(value,col=channel))+geom_histogram(bins=30)+facet_wrap(~ channel)

Interpretation:

What we immediately see from these histograms is that the middle values are in a sense over-used: there’s very few pixels with high or low values. Histogram equalisation solves the problem by making histograms flat: each pixel’s value is replaced by its rank, which is equivalent to running the data through their empirical cdf.

As an illustration of what this does, see the following example

x <- rnorm(100)
layout(t(1:2))
hist(x,main="Histogram of x")
f <- ecdf(x)
hist(f(x),main="Histogram of ecdf(x)")