Wednesday, July 6, 2011

Color reduction of an image - and Warholize?


There seems to be several methods out there for reducing the colors in an image. I became interested in this after pondering how this is done in the excellent freeware program IrfanView. Unfortunately, their method is not described anywhere that I could find, but I imagine that it is something along the tree data structure collapse method that ImageMagick employes.

The biOps package employes the k-means clustering to arrive at a reduced number of colors. I find that while this method takes a bit longer, the results can actually look a lot better. Just for kicks, I imbedded the imgKMeans() function in another function called warholize() that replaces these reduced color levels with another set. It's definitly not a Warhol, but I still like the effect.

the function...


#this function reduces the colors in a jpeg file to k levels using 
#the biOps function imgKMeans() and replaces those colors with those
#defined by the vector new.cols
warholize <- function(filename,k=4,maxit=10,new.cols=NULL){
 if(length(new.cols) != k) stop("length of new.cols must be equal to k")
 require(biOps)
 img <- imagedata(readJpeg(filename), type="rgb")
 img.red <- imgKMeans(img, k, maxit=maxit)
 col.names <- rgb(img.red[,,1],img.red[,,2],img.red[,,3],maxColorValue=255)
 col.unique <- unique(col.names)
 if(!is.null(new.cols) & is.character(new.cols)){
  new.cols<-col2rgb(new.cols)
  dim.img <- dim(img)
  img.temp <- as.matrix(img)
  dim(img.temp) <- c(dim.img[1]*dim.img[2], dim.img[3])
  col.num <- NA*1:length(col.names)
  for(i in 1:length(col.unique)){
   temp <- which(col.names == col.unique[i])
   col.num[temp] <- i
  }
  for(i in 1:3){
   img.red[,,i] <- matrix(new.cols[i,col.num], dim.img[1], dim.img[2])
  }
 }
 img.red
}
Created by Pretty R at inside-R.org


...and the code to create the above image (original image from Wikimedia Commons)...
marilyn.warholized <- warholize("Marilyn_Monroe_in_The_Prince_and_the_Showgirl_trailer_cropped.jpg",k=3, new.cols=c("red", "blue", "white"))
writeJpeg("marilyn.warholized.jpg",marilyn.warholized) 
Created by Pretty R at inside-R.org

No comments:

Post a Comment