Exploring Art Data 13

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]])

haystack-screenshot.pngWe’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)

brightness-histogram.pngColour 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.pngColour 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)

colour-cloud.pngImage 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
Posted in Aesthetics, Art Computing, Art Open Data