将浮点值(0.0、100.0)映射到RGB中



我有大约1000个浮动值,范围为(0.0,100.0),我想将这些值映射到一种颜色(RGB)中。到目前为止,我所做的是创建一个具有1000个颜色(RGB)值的颜色图,使用浮点值对颜色图进行索引并获得RGB值。

但问题是,我失去了精度,因为在使用浮点值作为颜色映射的索引之前,我将浮点值强制转换为int。进行浮点到rgb转换的最佳方法是什么?

编辑:

color color_list[100];
float float_values[1000]
for(i = 0 to 999)
{
   int colormap_idx = float_values[i];  // Note that the float is converted into an int
   color current_color = color_list[colormap_idx];
}

您可以拥有的RGB值总数为256^3。如果你能利用所有这些,那就太好了,但有时很难想出一个好的直观映射。由于总共可能有256^4个浮动(比可能的RGB值多),无论你做什么,你都会失去精度,但你仍然可以做得比现在好得多。

我不知道你对预定义的颜色图做了什么,但可以考虑只定义与几个中间浮点值相对应的几个中间颜色,并对每个输入浮点值进行插值。在下面的代码中,fsample和csample是您的对应点。例如:

fsample[0] = 0.0   -> csample[0] = (0, 0, 0)
fsample[1] = 0.25  -> csample[1] = (0, 0, 100)
fsample[2] = 0.5   -> csample[2] = (0, 170, 170)
fsample[3] = 0.75  -> csample[3] = (170, 170, 0)
fsample[4] = 1.0   -> csample[4] = (255, 255, 255)

这将允许您在RGB空间中使用浮动覆盖更多的区域,从而实现更高精度的转换,同时还可以灵活地定义中间颜色。这是一种将灰度转换为颜色的常用方法。

有一些优化和错误检查可以应用于此代码,但为了清晰起见,我没有对其进行优化:

int N = float_values.size();
color colormap[N];
for(i = 0 to N)
{
    colormap[i] = RGBFromFloat(float_values[i], fsample, csample, num_samples);
}

color RGBFromFloat(float in, float fsample[], float csample[], num_samples)
{
    color out;
    // find the interval that the input 'in' lies in
    // this is a simple search on an ordered array...
    // consider replacing with a better algorithm for a large number of samples
    for(i = 0 to num_samples-1)
    {
        if(fsample[i] =< in && in < fsample[i+1])
        {
             out = interpolate(fsample[i], fsample[i+1], csample[i], csample[i+1], in);    
             break;
        }
    }
    return color;
}
color interpolate(float flow, float fhigh, color clow, color chigh, float in)
{
    float t = (in-flow)/(fhigh-flow);
    return clow*(1 - t) + chigh*t
}

我不知道这是否是最好的方法(因为你没有给我们最优性标准),但如果你说的"我正在失去精度"意味着一旦转换为int,你最多只能有100种不同的颜色组合,那么你可以这样做:

// this code is C99
#define MAX_FLOAT_VAL 100.0
#define N_COLORS 2000
#define N_FLOAT_SAMPLES 1000
color color_list[N_COLORS];
float float_values[N_FLOAT_SAMPLES];
// the following loop must be placed in some function
for( int i = 0; i < N_FLOAT_SAMPLES; i++ )
{
    // the following assignment will map 
    // linearly a float in the range [0 ... MAX_FLOAT_VAL]
    // into an int in the range [0 ... (N_COLORS-1)]
    int colormap_idx = (float_values[i] / MAX_FLOAT_VAL) * (N_COLORS - 1);
    color current_color = color_list[colormap_idx];
    // ... do something with current_color ...
}

当然,您仍然需要使用合适的算法在color_list中生成条目(我建议不要手动生成:-)。这是一个完全不同的问题,因为它涉及更多的"自由度",因为你试图将一维空间(colormap_idx的值)映射到三维空间(所有可能的RGB三元组的集合)。

p.S:你的要求似乎让我想起了将分形着色所需的计算,就像Mandelbrot集合的图形表示一样。

希望这能有所帮助。

最新更新