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")
 img <- imagedata(readJpeg(filename), type="rgb") <- imgKMeans(img, k, maxit=maxit)
 col.names <- rgb([,,1],[,,2],[,,3],maxColorValue=255)
 col.unique <- unique(col.names)
 if(!is.null(new.cols) & is.character(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){[,,i] <- matrix(new.cols[i,col.num], dim.img[1], dim.img[2])
Created by Pretty R at

...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"))
Created by Pretty R at

No comments:

Post a Comment