【问题标题】:From hex color code or RGB to color name using R从十六进制颜色代码或 RGB 到使用 R 的颜色名称
【发布时间】:2017-05-03 17:25:22
【问题描述】:

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

       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

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

这里讨论上面输出的代码:Image colors composition using R

【问题讨论】:

标签: r image-processing colors rgb


【解决方案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

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

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

如果我正确理解了您问题的第二部分,那么从这一点获得相对比例应该不会太棘手。

【讨论】:

    【解决方案2】:

    方法类似于@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 
    

    情节:

    【讨论】:

      猜你喜欢
      • 2017-04-11
      • 2011-01-28
      • 2011-10-02
      • 1970-01-01
      • 2014-04-25
      • 2015-04-12
      • 2021-02-17
      • 1970-01-01
      相关资源
      最近更新 更多