Let’s go back and explore one image from the Haystacks series further. We’ll be able to apply these same techniques to the whole series (and to large imagesets) later.
We’ll use the thumbnail of the first image in the series:
display(artworksThumbnails[[1]])
We’ve already got a box plot of its brightness and a plot of its palette. Now we will create a brightness histogram, a colour histogram, and measure its brightness, mean of brightness SD, and entropy (visual complexity).
Brightness histogram:
## Plot brightness histogram hist(imageData(grayscaleArtworksThumbnails[[1]]),
main=names(grayscaleArtworksThumbnails)[1],
breaks=0:255/255, xlim=c(0, 1), xlab="Value", col=grey(0), border=NULL)
Colour Histogram (based on the work of Dr. Sai Chaitanya Gaddam):
## install.packages("plyr") # for ddply library(plyr) ## Colour histogram ## http://cns.bu.edu/~gsc/ColorHistograms.html binResolution<-25 colourImageHist<-function(bitmap, binResolution){ rgbs<-imagePixelsRGBs(bitmap) scaledRGBs<-floor(rgbs * binResolution) counts<-ddply(scaledRGBs, .(red, green, blue), nrow) names(counts)[4]<-"count" attr(counts, "binResolution")<-binResolution counts } colourHist<-colourImageHist(artworksThumbnails[[1]], binResolution) ## Plot colour histogram plotColourHist<-function(colourHist){ values<-apply(colourHist, 1, function(row){sum(row[c(1, 2, 3)])}) valuesOrder<-order(values) countsOrdered<-colourHist$count[valuesOrder] binResolution<-attr(colourHist, "binResolution") colours<-apply(colourHist, 1, function(row){rgb(row[1] / binResolution, row[2] / binResolution, row[3] / binResolution)}) coloursOrdered<-colours[valuesOrder] barplot(countsOrdered, col=coloursOrdered, border=NA) } plotColourHist(colourHist)
Colour histogram cloud (based on the work of Dr. Sai Chaitanya Gaddam):
## Plot colour cloud ## http://cns.bu.edu/~gsc/ColorHistograms.html sigmoid<-function(x){ 1 / (1 + exp(-x)) } colourCloudX<-function(r,g,b){ sigmoid((g - r + 1) / 2) } colourCloudY<-function(r,g,b){ eps<-length(colours) (b + eps)/(r + g + b + 3 * eps) } randomPointInRadius<-function(x, y, radius){ q<-runif(1) * (pi * 2) r<-radius * sqrt(runif(1)) h<-r * cos(q) v<-r * sin(q) c(x + h, y + v) } randomizedBinPoints<-function(xs, ys, radius){ coords<-array(dim=c(length(xs), 2)) for(index in 1:length(xs)){ point<-randomPointInRadius(xs[index], ys[index], radius) coords[index, 1]<-point[1] coords[index, 2]<-point[2] } coords } colourCloud<-function(hist, title="", radius=0.005, dotSize=1){ binResolution<-attr(hist, "binResolution") bins<-hist[c(1,2,3)] / binResolution ## Rep each item by the count that applies to its bin, this allows us to ## process the repeated item lists directly rather than nest loops & counters xs<-rep(apply(bins, 1, function(col){colourCloudX(col[1], col[2], col[3])}), hist$count) ys<-rep(apply(bins, 1, function(col){colourCloudY(col[1], col[2], col[3])}), hist$count) hexes<-rep(apply(bins, 1, function(c){rgb(c[1], c[2], c[3])}), hist$count) coords<-randomizedBinPoints(xs, ys, radius) plot(coords[,1], coords[,2], bg=hexes, main=title, cex=dotSize, col=NULL, pch=21, xlab="", ylab="", xaxt="n", yaxt="n") } colourCloud(colourHist)
Image brightness mean (not very interesting for a single image):
mean(unlist(imageData(grayscaleArtworksThumbnails[[1]])))
[1] 0.6130143
Mean of image brightness standard deviation:
mean(sd(unlist(imageData(grayscaleArtworksThumbnails[[1]]))))
[1] 0.1069661
Image brightness entropy:
## Calculate image entropy imageEntropy<-function(histogram){ nonzeroCounts<-histogram$counts[histogram$counts > 0] probs<-nonzeroCounts / sum(nonzeroCounts) -sum(probs * log2(probs)) } imageEntropy(hist(imageData(grayscaleArtworksThumbnails[[1]]), breaks=0:255/255, plot=FALSE))
[1] 7.112374
Image colour entropy:
imageEntropy(hist(imageData(artworksThumbnails[[1]]), breaks=0:255/255, plot=FALSE))
[1] 7.572906