使用R从十六进制颜色代码或RGB到颜色名称

时间:2016-12-18 14:37:49

标签: r image-processing colors rgb

我试图在给出图片的情况下计算每种颜色的百分比。在这一步我有这个输出:

       Color Count red green blue
861  ED1B24 16774 237    27   36
1    000000 11600   0     0    0
18   23B14D  5427  35   177   77
1996 FFFFFF  5206 255   255  255
1547 FEF200  3216 254   242    0
862  ED1B26   344 237    27   38

现在我想添加另一个带有颜色名称的列,然后计算百分比。我该怎么做?我想我也必须聚合一些颜色。 TNX

此处讨论上述输出的代码:Image colors composition using R

2 个答案:

答案 0 :(得分:1)

您可以决定一些距离度量,然后搜索R颜色,以最小化到每种颜色的距离。它听起来计算成本很高,但事实证明它很快。

例如,使用您提供的数据框:

> col_data
      Color Count red green blue
861  ED1B24 16774 237    27   36
1    000000 11600   0     0    0
18   23B14D  5427  35   177   77
1996 FFFFFF  5206 255   255  255
1547 FEF200  3216 254   242    0
862  ED1B26   344 237    27   38

我们可以创建另一个数据框,其中包含R:

中定义的颜色的RGB值
r_colors <- data.frame(color = colors())
r_colors <- cbind(r_colors, t(col2rgb(colors())))

这会产生类似于:

的内容
> head(r_colors)
          color red green blue
1         white 255   255  255
2     aliceblue 240   248  255
3  antiquewhite 250   235  215
4 antiquewhite1 255   239  219
5 antiquewhite2 238   223  204
6 antiquewhite3 205   192  176

(点点点)

> tail(r_colors)
          color red green blue
652      yellow 255   255    0
653     yellow1 255   255    0
654     yellow2 238   238    0
655     yellow3 205   205    0
656     yellow4 139   139    0
657 yellowgreen 154   205   50

使用欧几里德距离来映射上面r_data中的颜色:

col_data$color_name <- sapply(
  seq_along(col_data$Color),
  function(i) 
    r_colors$color[
      which.min(
        (r_colors$red - col_data$red[i])^2 +
          (r_colors$green - col_data$green[i])^2 +
          (r_colors$blue - col_data$blue[i])^2
      )
    ]
)

我们得到数据框:

> col_data
      Color Count red green blue color_name
861  ED1B24 16774 237    27   36 firebrick2
1    000000 11600   0     0    0      black
18   23B14D  5427  35   177   77   seagreen
1996 FFFFFF  5206 255   255  255      white
1547 FEF200  3216 254   242    0     yellow
862  ED1B26   344 237    27   38 firebrick2

当然,颜色可能不完全匹配,但它们非常相似。下图显示了相应的最近R颜色(右侧)旁边的col_data(左侧)中的颜色。

Comparison of colours to nearest neighbour in RGB-space

(从技术上讲,我们只是在RGB空间中搜索最近的邻居。)

如果我理解你的问题的第二部分,从这一点获得相对比例不应该太棘手。

答案 1 :(得分:0)

方法类似于@Richard Ambler的解决方案来比较测试rgb矢量和 从colours()的输出中扩展的颜色映射集。

下面的函数rgb2col给定的测试rgb值返回近似匹配的颜色名称

数据:

library(scales) #for function show_col

DF = read.table(text="Color Count red green blue
 ED1B24 16774 237    27   36
 000000 11600   0     0    0
 23B14D  5427  35   177   77
 FFFFFF  5206 255   255  255
 FEF200  3216 254   242    0
 ED1B26   344 237    27   38",header=TRUE,stringsAsFactors=FALSE)


 #from https://gist.github.com/mbannert/e9fcfa86de3b06068c83

 rgb2hex <- function(r,g,b) rgb(r, g, b, maxColorValue = 255)

<强>功能:

 rgb2col = function(r,g,b) {

 #create colour name vs. rgb mapping table 
 colourMap = data.frame(colourNames = colours(),t(col2rgb(colours())))

 #input test colours
 testDF = data.frame(colourNames="testCol",red = r,green = g,blue = b)

 #combine both tables
 combDF = rbind(testDF,colourMap)

 #convert in matrix representation 
 combMat= (as.matrix(combDF[,-1]))

 #add row labels as colour names
 rownames(combMat) = combDF[,1]

 #compute euclidean distance between test rgb vector and all the colours
 #from mapping table 
 #using dist function compute distance matrix,retain only upper matrix
 #find minimum distance point from test vector

 #find closest matching colour name
 approxMatchCol = which.min(as.matrix(dist(combMat,upper=TRUE))[1,][-1])

 #compare test colour with approximate matching colour
 scales::show_col(c(rgb2hex(r,g,b),rgb2hex(colourMap[approxMatchCol,2:4])))

 #return colour name
 return(approxMatchCol)

 }

<强>输出:

sapply(1:nrow(DF),function(x) rgb2col(DF[x,"red"],DF[x,"green"],DF[x,"blue"]))
#firebrick2      black   seagreen      white     yellow firebrick2 
#       135         24        574          1        652        135 

<强>图:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here