[R] measuring distances between colours?
Ken Knoblauch
ken.knoblauch at inserm.fr
Sat Jun 1 18:17:39 CEST 2013
Hi John,
Out of curiosity and if it is not much trouble, I would be curious if Luv worked any better than Lab. I think that Luv is supposed to be preferred for monitors and Lab for surfaces but they are generally pretty similar.
Best,
Ken
Sent from my iPhone
___
Ken Knoblauch
Inserm U846
Stem-Cell and Brain Research Institute
18 av du Doyen Lépine
69500 Bron France
Tel : 04 72 91 34 77
Fax : 04 72 91 34 61
portable : 06 84 10 64 10
http://www.sbri.fr/members/kenneth-knoblauch.html
On 1 juin 2013, at 17:31, "John Fox" <jfox at mcmaster.ca> wrote:
> Hi Michael,
>
> Thanks for the Wikipedia tip -- I'd looked there but didn't find this
> article. The article explains that the Lab colour space was formulated to
> provide uniform perceptual differences between colours, with a JND of
> approximately of 2.3. Ken Knoblauch made a similar point. The article goes
> on to describe relatively complicated adjustments meant to improve the LAV
> distance metric, which are probably overkill for my application.
>
> I've programmed Lab colour matching as follows, using Euclidean distances
> and adapting Kevin Wright's modification of my original code. I used
> convertColor(), which Martin Maechler pointed out to me.
>
> ----------- snip --------------
>
> r2c <- function(){
> all.names <- colors()
> all.lab <- t(convertColor(t(col2rgb(all.names)), from="sRGB", to="Lab",
> scale.in=255))
> find.near <- function(x.lab) {
> sq.dist <- colSums((all.lab - x.lab)^2)
> rbind(all.names[which.min(sq.dist)], min(sq.dist))
> }
> function(cols.hex, near=2.3){
> cols.lab <- t(convertColor(t(col2rgb(cols.hex)), from="sRGB",
> to="Lab", scale.in=255))
> cols.near <- apply(cols.lab, 2, find.near)
> ifelse(cols.near[2, ] < near^2, cols.near[1, ], cols.hex)
> }
> }
>
> rgb2col <- r2c()
>
> ----------- snip --------------
>
> A bit of experimentation suggests that this works better than using (as I
> did previously) direct RGB distances, matching more colours to names and
> providing (to my eye, with my monitor) perceptually closer matches, though
> sometimes with (again to my eye) perceptible differences. Here's an
> illustration, adapting one of Kevin's examples:
>
> ----------- snip --------------
>
> cols <- c("#010101", "#EEEEEE", "#AA0000", "#00AA00", "#0000AA", "#AAAA00",
> "#AA00AA", "#00AAAA")
> (nms <- rgb2col(cols))
> pie(rep(1, 2*length(cols)), labels=c(cols, nms), col=c(cols, nms))
>
> ----------- snip --------------
>
> Thanks again to everyone who responded to my original, naïve, question.
>
> Best,
> John
>
>> -----Original Message-----
>> From: Michael Friendly [mailto:friendly at yorku.ca]
>> Sent: Friday, May 31, 2013 10:24 AM
>> To: John Fox
>> Cc: r-help at r-project.org; 'Martin Maechler'
>> Subject: Re: measuring distances between colours?
>>
>> Hi John
>> This has been an interesting discussion.
>> Though you have a solution for your needs, you might be interested in
>> this javascript implementation that allows you to visually compare
>> color
>> distances in various color spaces
>>
>> http://stevehanov.ca/blog/index.php?id=116
>>
>> And, all the theory of color distance is described in
>> http://en.wikipedia.org/wiki/Color_difference
>>
>> PS: This is a very handy function. When I last tried
>> aplpack::bagplot(), it was annoying that the colors could *only*
>> be specified in hex.
>>
>> -Michael
>>
>>
>>
>> On 5/30/2013 5:14 PM, John Fox wrote:
>>> Dear all,
>>>
>>> My thanks to everyone who addressed my question. I've incorporated
>> Eik
>>> Vettorazzi's suggestion for improved conversion of hexadecimal RGB
>> colours
>>> to decimal numbers, and Martin Maechler's hint to look at
>> demo(colors). I've
>>> loosened the default definition of "close enough" from the latter,
>> since the
>>> following seems to work well for my purposes.
>>>
>>> r2c <- function(){
>>> hex2dec <- function(hexnums) {
>>> # suggestion of Eik Vettorazzi
>>> sapply(strtoi(hexnums, 16L), function(x) x %/% 256^(2:0) %%
>> 256)
>>> }
>>> findMatch <- function(dec.col) {
>>> sq.dist <- colSums((hsv - dec.col)^2)
>>> rbind(which.min(sq.dist), min(sq.dist))
>>> }
>>> colors <- colors()
>>> hsv <- rgb2hsv(col2rgb(colors))
>>> function(cols, near=0.25){
>>> cols <- sub("^#", "", toupper(cols))
>>> dec.cols <- rgb2hsv(hex2dec(cols))
>>> which.col <- apply(dec.cols, 2, findMatch)
>>> matches <- colors[which.col[1, ]]
>>> unmatched <- which.col[2, ] > near^2
>>> matches[unmatched] <- paste("#", cols[unmatched], sep="")
>>> matches
>>> }
>>> }
>>>
>>> rgb2col <- r2c()
>>>
>>> For example,
>>>
>>>> rgb2col(c("010101", "EEEEEE", "AA0000", "00AA00", "0000AA",
>> "AAAA00",
>>> "AA00AA", "00AAAA"))
>>> [1] "black" "gray93" "darkred" "green4"
>>> [5] "blue4" "darkgoldenrod" "darkmagenta" "cyan4"
>>>
>>>> rgb2col(c("010101", "090909", "090000", "000900", "000009",
>> "090900",
>>> "090009", "000909"))
>>> [1] "black" "gray3" "#090000" "#000900" "#000009" "#090900"
>>> [7] "#090009" "#000909"
>>>
>>> Thanks again,
>>> John
>>
>>
>> --
>> Michael Friendly Email: friendly AT yorku DOT ca
>> Professor, Psychology Dept. & Chair, Quantitative Methods
>> York University Voice: 416 736-2100 x66249 Fax: 416 736-5814
>> 4700 Keele Street Web: http://www.datavis.ca
>> Toronto, ONT M3J 1P3 CANADA
>
More information about the R-help
mailing list