C# 生成具有高区分的随机颜色值

C# 生成具有高区分的随机颜色值

在很多应用场景中经常会用到多个高区分颜色值来标记不同物体,比如:不容数据曲线标记、边缘计算、图像处理等。

RGB 的局限性

RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色(R),绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色,当然经常也伴随着通过透明度(A)来形成更多的表现形式。

RGB 颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间,比较容易理解。

RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。

自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。

但是人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。

所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理。

RGB颜色值转十六进制颜色值-阿里云开发者社区

HSV 颜色空间

基于上述理由,在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。

在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相)

  • Saturation(饱和度、色彩纯净度)

  • Value(明度)

    用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。

RGB、HSV和HSL颜色空间- 知乎

HLS 颜色空间

HLS 和 HSV 比较类似,这里一起介绍。HLS 也有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。

HLS 和 HSV 的区别就是最后一个分量不同,HLS 的是 light(亮度),HSV 的是 value(明度)。

HLS 中的 L 分量为亮度,亮度为100,表示白色,亮度为0,表示黑色;HSV 中的 V 分量为明度,明度为100,表示光谱色,明度为0,表示黑色。

img

结论

综上所述,在图形识别等领域中使用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);
	}
}

通过曲线颜色区分不同数据源,显示结果:

image-20210315095946593

参考:RGB、HSV和HSL颜色空间

posted @ 2021-03-15 10:08  MarkYUN  阅读(2289)  评论(2)    收藏  举报