Hi Jim,

Thanks for this. 

Ben's function makes comparisons in the RGB rather than the HSV colour space; 
works on the decimal rather than hex representation of colours; applies to a 
single colour rather than a vector; recomputes the CSV representation of the 
named colours each time it's called rather than using a closure; and returns 
more than one colour when there are ties for the best match. But otherwise, the 
two functions are similar, in that each is based on Euclidean distance in the 
colour space. 

My superficial reading about colour spaces suggested that distances in the HSV 
space are more closely related to perceptual differences in colours than are 
distances in the RGB space. 

Best,
 John

On Thu, 30 May 2013 22:30:18 +1000
 Jim Lemon <j...@bitwrit.com.au> wrote:
> On 05/30/2013 10:13 PM, John Fox wrote:
> > Dear r-helpers,
> >
> > I'm interested in locating the named colour that's "closest" to an 
> > arbitrary RGB colour. The best that I've been able to come up is the 
> > following, which uses HSV colours for the comparison:
> >
> > r2c<- function(){
> >      hexnumerals<- 0:15
> >      names(hexnumerals)<- c(0:9, LETTERS[1:6])
> >      hex2decimal<- function(hexnums){
> >          hexnums<- strsplit(hexnums, "")
> >          decimals<- matrix(0, 3, length(hexnums))
> >          decimals[1, ]<- sapply(hexnums, function(x)
> >                                   sum(hexnumerals[x[1:2]] * c(16, 1)))
> >          decimals[2, ]<- sapply(hexnums, function(x)
> >                                   sum(hexnumerals[x[3:4]] * c(16, 1)))
> >          decimals[3, ]<- sapply(hexnums, function(x)
> >                                   sum(hexnumerals[x[5:6]] * c(16, 1)))
> >          decimals
> >      }
> >      colors<- colors()
> >      hsv<- rgb2hsv(col2rgb(colors))
> >      function(cols){
> >          cols<- sub("^#", "", toupper(cols))
> >          dec.cols<- rgb2hsv(hex2decimal(cols))
> >          colors[apply(dec.cols, 2, function(dec.col)
> >              which.min(colSums((hsv - dec.col)^2)))]
> >      }
> > }
> >
> > rgb2col<- r2c()
> >
> > I've programmed this with a closure so that hsv gets computed only once.
> >
> > Examples:
> >
> >> rgb2col(c("AA0000", "002200", "000099", "333300", "BB00BB", "#005555"))
> > [1] "darkred"   "darkgreen" "blue4"     "darkgreen" "magenta3"  "darkgreen"
> >> rgb2col(c("AAAA00", "#00AAAA"))
> > [1] "darkgoldenrod" "cyan4"
> >
> > Some of these colour matches, e.g., "#005555" ->  "darkgreen" seem poor to 
> > me. Even if the approach is sound, I'd like to be able to detect that there 
> > is no sufficiently close match in the vector of named colours. That is, can 
> > I establish a maximum acceptable distance in the HSV (or some other) colour 
> > space?
> >
> > I vaguely recall a paper or discussion concerning colour representation in 
> > R but can't locate it.
> >
> > Any suggestions would be appreciated.
> >
> > John
> >
> Hi John,
> Ben Bolker contributed a function (color.id) to the plotrix package that does 
> something like this. Although it uses RGB colorspace, it might be useful:
> 
> color.id<-function (col) {
>      c2 <- col2rgb(col)
>      coltab <- col2rgb(colors())
>      cdist <- apply(coltab, 2, function(z) sum((z - c2)^2))
>      colors()[which(cdist == min(cdist))]
> }
> 
> Jim

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to