如果我得到浅灰色(例如 R=G=B=200)和深色(例如 R=46,G=41,B=35),我想将它们都分类为简单灰色组(想象一张桌子)。
那么,如何将颜色组织到颜色组中?
对于颜色的视觉分类,首先将颜色转换为 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>
颜色分类有几种方法。一种方法是将 rgb 视为 3d 坐标,然后可以在一个盒子或立方体内表示所有可能的颜色,其中黑色位于原点,白色位于对角(255,255,255)。所有灰色颜色将位于靠近对角线的位置。 以及靠近轴的红色、绿色和蓝色。 这样,分类问题就转变为寻找 3d 空间中点(颜色)和线(灰色对角线)之间的最近距离。如果距离低于给定阈值,则颜色将被分类为灰色。
下面的颜色表实现怎么样:
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();