如何将某些颜色分类到颜色范围?

问题描述 投票:0回答:3

如果我得到浅灰色(例如 R=G=B=200)和深色(例如 R=46,G=41,B=35),我想将它们都分类为简单灰色组(想象一张桌子)。

那么,如何将颜色组织到颜色组中?

c# wpf colors rgb
3个回答
22
投票

对于颜色的视觉分类,首先将颜色转换为 HSL 或 HSV 通常更容易。要检测灰色,请检查饱和度是否低于某个阈值。要检测任何其他颜色,请检查色调。

public string Classify(Color c)
{
    float hue = c.GetHue();
    float sat = c.GetSaturation();
    float lgt = c.GetLightness();

    if (lgt < 0.2)  return "Blacks";
    if (lgt > 0.8)  return "Whites";

    if (sat < 0.25) return "Grays";

    if (hue < 30)   return "Reds";
    if (hue < 90)   return "Yellows";
    if (hue < 150)  return "Greens";
    if (hue < 210)  return "Cyans";
    if (hue < 270)  return "Blues";
    if (hue < 330)  return "Magentas";
    return "Reds";
}

你当然可以使用其他一些部门。

我制作了一个简单的 JavaScript 应用程序来测试这一点:

function classify(r, g, b) {
  let [hue, sat, lgt] = rgbToHsl(r, g, b);
  if (lgt < 0.2) return "Blacks";
  if (lgt > 0.8) return "Whites";

  if (sat < 0.25) return "Grays";

  if (hue < 30) return "Reds";
  if (hue < 90) return "Yellows";
  if (hue < 150) return "Greens";
  if (hue < 210) return "Cyans";
  if (hue < 270) return "Blues";
  if (hue < 330) return "Magentas";
  return "Reds";
}

document.addEventListener('DOMContentLoaded', () => main());

function main() {
  let result = document.querySelector('#result > tbody');
  for (let r = 0; r <= 0xFF; r += 0x33) {
    for (let g = 0; g <= 0xFF; g += 0x33) {
      for (let b = 0; b <= 0xFF; b += 0x33) {
        let hex = '#' + ((r * 256 + g) * 256 + b).toString(16).padStart(6, '0').toUpperCase();
        let tr = document.createElement('tr');
        let td1 = document.createElement('td');
        let box = document.createElement('div');
        box.className = 'color-box';
        box.style.backgroundColor = hex;
        td1.appendChild(box);
        td1.appendChild(document.createTextNode(hex));
        tr.appendChild(td1);
        let td2 = document.createElement('td');
        td2.innerText = classify(r, g, b);
        tr.appendChild(td2);
        result.appendChild(tr);
      }
    }
  }
}

// Based on: https://www.30secondsofcode.org/js/s/rgb-hex-hsl-hsb-color-format-conversion/#rgb-to-hsl
function rgbToHsl(r, g, b) {
  r /= 255;
  g /= 255;
  b /= 255;
  const l = Math.max(r, g, b);
  const s = l - Math.min(r, g, b);
  const h = s ?
    l === r ?
    (g - b) / s :
    l === g ?
    2 + (b - r) / s :
    4 + (r - g) / s :
    0;
  return [
    60 * h < 0 ? 60 * h + 360 : 60 * h,
    (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
    (2 * l - s) / 2
  ];
}
.color-box {
  display: inline-block;
  width: 2em;
  height: 1em;
  margin-right: 0.5em;
  border: 1px solid black;
}
<table id="result">
  <thead>
    <tr>
      <th>Color</th>
      <th>Classification</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>


2
投票

颜色分类有几种方法。一种方法是将 rgb 视为 3d 坐标,然后可以在一个盒子或立方体内表示所有可能的颜色,其中黑色位于原点,白色位于对角(255,255,255)。所有灰色颜色将位于靠近对角线的位置。 以及靠近轴的红色、绿色和蓝色。 这样,分类问题就转变为寻找 3d 空间中点(颜色)和线(灰色对角线)之间的最近距离。如果距离低于给定阈值,则颜色将被分类为灰色。


-1
投票

下面的颜色表实现怎么样:

public class ColorTable
{
    public Color ColorName { get; set; } //can set color code too
    public string GroupName { get; set; }

}

并编写以下代码来生成/获取颜色组:

//Generating Color Group Table
List<ColorTable> MyColorTable = new List<ColorTable>();
MyColorTable.Add(new ColorTable { GroupName = "Gray", ColorName = Color.Gray });
MyColorTable.Add(new ColorTable { GroupName = "Gray", ColorName = Color.LightGray });
MyColorTable.Add(new ColorTable { GroupName = "Green", ColorName = Color.Green });
MyColorTable.Add(new ColorTable { GroupName = "Green", ColorName = Color.LightGreen });

//Getting required Color Group, say "Gray"
List<ColorTable> GreenColor = MyColorTable.Where(c => c.GroupName == "Gray").ToList();
© www.soinside.com 2019 - 2024. All rights reserved.