C# 生成具有高区分的随机颜色值
C# 生成具有高区分的随机颜色值
在很多应用场景中经常会用到多个高区分颜色值来标记不同物体,比如:不容数据曲线标记、边缘计算、图像处理等。
RGB 的局限性
RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色(R),绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色,当然经常也伴随着通过透明度(A)来形成更多的表现形式。
RGB 颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间,比较容易理解。
RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。
自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。
但是人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。
所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理。
HSV 颜色空间
基于上述理由,在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。
在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。
HSV 表达彩色图像的方式由三个部分组成:
-
Hue(色调、色相)
-
Saturation(饱和度、色彩纯净度)
-
Value(明度)
用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。
HLS 颜色空间
HLS 和 HSV 比较类似,这里一起介绍。HLS 也有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。
HLS 和 HSV 的区别就是最后一个分量不同,HLS 的是 light(亮度),HSV 的是 value(明度)。
HLS 中的 L 分量为亮度,亮度为100,表示白色,亮度为0,表示黑色;HSV 中的 V 分量为明度,明度为100,表示光谱色,明度为0,表示黑色。

结论
综上所述,在图形识别等领域中使用HLS/HSV是比较合适的选择。
1、 首先随机生成到指定个数的HLS值
/// <summary>
/// 获取随机HLS值
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
public static List<ColorHSL> GetRandHLSColor(int num)
{
List<ColorHSL> colors = new List<ColorHSL>();
int i = 0;
int step = (int)(360.0 / num);
Random rand = new Random();
while (i < 360)
{
int h = i;
double s = 90 + rand.NextDouble() * 10;
double l = 50 + rand.NextDouble() * 10;
ColorHSL hlsc = new ColorHSL(h: (float)(h / 360.0), s: (float)(s / 100.0), l: (float)(l / 10
colors.Add(hlsc);
i += step;
}
return colors;
}
2、将获得的HLS值进行RGB转换
/// <summary>
/// HSL转换RGB
/// </summary>
/// <param name="hsl"></param>
/// <returns></returns>
public static ColorRGB MyHslToRgb(ColorHSL hsl)
{
float R = 0f, G = 0f, B = 0f;
float S = hsl.S , L = hsl.L+0.1f;
float temp1, temp2, temp3;
if (S == 0f) // 灰色
{
R = L;
G = L;
B = L;
}
else
{
if (L < 0.5f)
{
temp2 = L * (1.0f + S);
}
else
{
temp2 = L + S - (L * S);
}
temp1 = 2.0f * L -
float H = hsl.H;
// R
temp3 = H + (1.0f /
R = ConvertComputer1(temp1, temp2, temp3);
// G
temp
G = ConvertComputer1(temp1, temp2, temp3) ;
// B
temp3 = H - (1.0f /
B = ConvertComputer1(temp1, temp2, temp3) ;
}
R = (int)(R * 255.0);
G = (int)(G * 255.0);
B = (int)(B * 255.0);
return new ColorRGB((int)R, (int)G, (int)B);
}
3、调用方法获取所需的颜色值
/// <summary>
/// 获取高区分的指定个数颜色值
/// </summary>
/// <param name="num">颜色值个数</param>
/// <returns></returns>
public static List<ColorRGB> GetRGBColors(int num)
{
List<ColorRGB> colorRGBs = new List<ColorRGB>();
List<ColorHSL> hlss = GetRandHLSColor(num);
for (int i = 0; i < hlss.Count; i++)
{
ColorRGB color = ColorHelper.MyHslToRgb(hls
colorRGBs.Add(color);
}
return colorRGBs;
}
ColorRBG Class
public class ColorRGB
{
/// <summary>
/// 构造方法
/// </summary>
/// <param name="r"></param>
/// <param name="g"></param>
/// <param name="b"></param>
public ColorRGB(int r, int g, int b)
{
this._r = r;
this._g = g;
this._b = b;
}
private int _r;
private int _g;
private int
/// <summary>
/// 红色
/// </summary>
public int R
{
get { return this._r; }
set
{
this._r = value;
this._r = this._r > 255 ? 255 : this._r;
this._r = this._r < 0 ? 0 : this._r;
}
}
/// <summary>
/// 绿色
/// </summary>
public int G
{
get { return this._g; }
set
{
this._g = value;
this._g = this._g > 255 ? 255 : this._g;
this._g = this._g < 0 ? 0 : this._g;
}
}
/// <summary>
/// 蓝色
/// </summary>
public int B
{
get { return this._b; }
set
{
this._b = value;
this._b = this._b > 255 ? 255 : this._b;
this._b = this._b < 0 ? 0 : this._b;
}
}
/// <summary>
/// 获取实际颜色
/// </summary>
/// <returns></returns>
public Color GetColor()
{
return Color.FromArgb(this._r, this._g, this._b);
}
}
通过曲线颜色区分不同数据源,显示结果:


浙公网安备 33010602011771号