如何将温度值映射到相应的 RGB 索引

How to map the temperature values to corresponding RGB indexes

这是我的代码:

RGB_Struct RGB_TABLE[] =
{
    /* Temperature */
    {195, 209, 255},  
    {195, 210, 255}, 
    {196, 210, 255}, 
    {197, 210, 255}, 
    {197, 211, 255},
    {197, 211, 255},
    {198, 212, 255},
    {198, 212, 255},
    {199, 212, 255},
    {200, 213, 255},
    {200, 213, 255},
    {201, 214, 255},
    {202, 214, 255},
    {202, 215, 255},
    {203, 215, 255},
    {204, 216, 255},
    {204, 216, 255},
    {205, 217, 255},
    {206, 217, 255},
    {207, 218, 255},
    {207, 218, 255},
    {205, 220, 255},
    {206, 220, 255},
    {207, 221, 255},
    {207, 221, 255},
    {208, 222, 255},
    {209, 223, 255},
    {210, 223, 255},
    {211, 224, 255},
    {212, 225, 255},
    {214, 225, 255},
    {215, 226, 255},
    {216, 227, 255},
    {217, 227, 255},
    {218, 229, 255},
    {220, 229, 255},
    {221, 230, 255},
    {222, 230, 255},
    {224, 231, 255},
    {225, 232, 255},
    {227, 233, 255},
    {228, 234, 255},
    {230, 235, 255},
    {231, 236, 255},
    {233, 237, 255},
    {235, 238, 255},
    {237, 239, 255},
    {239, 240, 255},
    {240, 241, 255},
    {243, 242, 255},
    {245, 243, 255},
    {247, 245, 255},
    {249, 246, 255},
    {252, 247, 255},
    {254, 249, 255},
    {255, 249, 253},
    {255, 248, 251},
    {255, 246, 247},
    {255, 245, 245},
    {255, 244, 242},
    {255, 243, 239},
    {255, 242, 236},
    {255, 240, 233},
    {255, 239, 230},
    {255, 238, 227},
    {255, 236, 224},
    {255, 235, 220},
    {255, 233, 217},
    {255, 232, 213},
    {255, 230, 210},
    {255, 228, 206},
    {255, 227, 202},
    {255, 225, 198},
    {255, 223, 194},
    {255, 221, 190},
    {255, 219, 186},
    {255, 217, 182},
    {255, 215, 177},
    {255, 213, 173},
    {255, 211, 168},
    {255, 209, 163},
    {255, 206, 159},
    {255, 204, 153},
    {255, 201, 148},
    {255, 199, 143},
    {255, 196, 137},
    {255, 193, 132},
    {255, 190, 126},
    {255, 187, 120},
    {255, 184, 114},
    {255, 180, 107},
    {255, 177, 101},
    {255, 173, 94},
    {255, 169, 87},
    {255, 165, 79},
    {255, 161, 72},
    {255, 157, 63},
    {255, 152, 54},
    {255, 147, 44},
    {255, 142, 33},
    {255, 138, 18},
    {255, 131, 0},
    {255, 126, 0},
    {255, 121, 0},
    {255, 115, 0},
    {255, 109, 0},
    {255, 101, 0},
    {255, 93, 0},
    {255, 83, 0},
    {255, 71, 0},
    {255, 56, 0},
};

RGB_Struct ConvertTemperatureToRGB(float temperature)
{
    uint16_t index = 0;


    return TEMP_INDEX_TO_RGB_TABLE[index];
}

void heatmap(float *data, char *pixelDataPtr)
{
    int height = 8;
    int width = 8;
    unsigned char image[height][width][BYTES_PER_PIXEL];
    RGB_Struct rgbVaue;

    int i, j, k=0;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            rgbVaue = ConvertTemperatureToRGB(data[k++]);
            image[i][j][0] = rgbVaue.Red;
            image[i][j][1] = rgbVaue.Green;
            image[i][j][2] = rgbVaue.Blue;
        }
    
}

}

在代码中 create_heatmap(temp_c, Pixels); 将在 main 中调用,并且 temp_cfloat temp_c[64] 并且 Pixelschar Pixels[246]

温度值需要映射到 TEMP_INDEX_TO_RGB_TABLE[] 中的 RGB 值。 对于映射,我们需要索引来将 Temp 数据映射到 RGB 值。

帮我修改代码,让 64 个温度值根据它们的温度与 RGB 数据映射,我可以将温度读数映射在 20°C - 50°C 之间,分辨率为 0.25° c.

我会尽量让它变得简单,即得出一个索引,唯一困难的部分是处理不等式以达到您想要的范围,例如

    /* Temperature */ /* RGB Value */
    {195, 209, 255},  /* <= 0.00 °C */
    {195, 210, 255},  /* <= 0.25 °C */
    {196, 210, 255},  /* <= 0.50 °C */
    {197, 210, 255},  /* <= 0.75 °C */
    ...

注意上面,对于不为零但小于 0.25 摄氏度的值,所有值都由 table.

的第二个元素提供的值

让我们从简单的情况开始,我们只想将温度映射到您的 table 而无需担心范围。在那里,正如评论中提到的,因为你的 0 Deg C 对应于你的 table 的 0 元素,而你的 table 处理温度 .25 Deg C增量,您需要做的就是将 temperature 除以 .25 得到 index,例如

 RGB_Struct ConvertTemperatureToRGB(float temperature)
{
    uint16_t index = 0;

    index = (uint16_t)(temperature / .25);
    
    return TEMP_INDEX_TO_RGB_TABLE[index];
}

这将 return 一个有效的索引(只要您的温度不会导致索引超出 table 的末尾。但是,您的 returned table 索引将与您在注释中提供的范围不匹配。例如,上面将导致以下索引映射到 01 之间的 temperature,例如

temp: 0.00    R: 195  G: 255  B: 209
temp: 0.05    R: 195  G: 255  B: 209
temp: 0.10    R: 195  G: 255  B: 209
temp: 0.15    R: 195  G: 255  B: 209
temp: 0.20    R: 195  G: 255  B: 209
temp: 0.25    R: 195  G: 255  B: 210
temp: 0.30    R: 195  G: 255  B: 210
temp: 0.35    R: 195  G: 255  B: 210
temp: 0.40    R: 195  G: 255  B: 210
temp: 0.45    R: 195  G: 255  B: 210
temp: 0.50    R: 196  G: 255  B: 210
temp: 0.55    R: 196  G: 255  B: 210
temp: 0.60    R: 196  G: 255  B: 210
temp: 0.65    R: 196  G: 255  B: 210
temp: 0.70    R: 196  G: 255  B: 210
temp: 0.75    R: 197  G: 255  B: 210
temp: 0.80    R: 197  G: 255  B: 210
temp: 0.85    R: 197  G: 255  B: 210
temp: 0.90    R: 197  G: 255  B: 210
temp: 0.95    R: 197  G: 255  B: 210
temp: 1.00    R: 197  G: 255  B: 211

如果您查看,结果会偏离 1 个索引,并且不包括以 .25.50、... 为增量的适当范围内的温度。

这只是一道数学题,一道不等式。处理此问题的一种相当直接的方法是定义在值更改之前您希望与增量的接近程度。您可以定义限制并调整索引 returned,方法是使这些值达到但不包括下一个温度增量。例如,要在增量的 0.00005 范围内,您可以将限制定义为:

#define LIMIT 5e-5

然后捕获你想要的范围,计算索引变成:

      index = (uint16_t)((temperature + .25 - LIMIT) / .25);

在当前索引的下一个增量 LIMIT 范围内获取所有值。

如果您认识到 table 中的第一个元素的值小于或等于零摄氏度,您可以简单地将其视为特殊情况。你最后的 index 计算结果变成:

    if (temperature <= 0)
      index = 0;
    else
      index = (uint16_t)((temperature + .25 - LIMIT) / .25);

如果你把它放在一起(注意 index 已经初始化为 0 对于 0 的情况),你的函数变成:

RGB_Struct ConvertTemperatureToRGB(float temperature)
{
    uint16_t index = 0;

    if (temperature > 0)
      index = (uint16_t)((temperature + .25 - LIMIT) / .25);
    
    return TEMP_INDEX_TO_RGB_TABLE[index];
}

现在,检查值如何下降并与所需结果进行比较,例如

temp: 0.00    R: 195  G: 255  B: 209
temp: 0.05    R: 195  G: 255  B: 210
temp: 0.10    R: 195  G: 255  B: 210
temp: 0.15    R: 195  G: 255  B: 210
temp: 0.20    R: 195  G: 255  B: 210
temp: 0.25    R: 195  G: 255  B: 210
temp: 0.30    R: 196  G: 255  B: 210
temp: 0.35    R: 196  G: 255  B: 210
temp: 0.40    R: 196  G: 255  B: 210
temp: 0.45    R: 196  G: 255  B: 210
temp: 0.50    R: 196  G: 255  B: 210
temp: 0.55    R: 197  G: 255  B: 210
temp: 0.60    R: 197  G: 255  B: 210
temp: 0.65    R: 197  G: 255  B: 210
temp: 0.70    R: 197  G: 255  B: 210
temp: 0.75    R: 197  G: 255  B: 210
temp: 0.80    R: 197  G: 255  B: 211
temp: 0.85    R: 197  G: 255  B: 211
temp: 0.90    R: 197  G: 255  B: 211
temp: 0.95    R: 197  G: 255  B: 211
temp: 1.00    R: 197  G: 255  B: 211

根据您的评论,它与所需的索引相匹配。设置数学的方式没有任何魔力——您可以通过多种方式进行设置,只要您在正确的索引中捕获正确的值范围即可。这基本上只是一个缩放问题。

示例代码

为了验证,以下代码是您问题中的一小段简单代码:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

typedef struct
{
    uint8_t Red;
    uint8_t Blue;
    uint8_t Green;
} RGB_Struct;

/**
 * Temperature range of measuring object = 0 °C to 80 °C (or) +32 °F to +176 °F
 * with resolution = 0.25 °C
 */
RGB_Struct TEMP_INDEX_TO_RGB_TABLE[] =
{
    /* Temperature */ /* RGB Value */
    {195, 209, 255},  /* <= 0.00 °C */
    {195, 210, 255},  /* <= 0.25 °C */
    {196, 210, 255},  /* <= 0.50 °C */
    {197, 210, 255},  /* <= 0.75 °C */
    {197, 211, 255},
    {197, 211, 255},
    {198, 212, 255},
    {198, 212, 255},
    {199, 212, 255},
    {200, 213, 255},
    {200, 213, 255},
    {201, 214, 255},
    {202, 214, 255},
    {202, 215, 255},
    {203, 215, 255},
    {204, 216, 255},
    {204, 216, 255},
    {205, 217, 255},
    {206, 217, 255},
    {207, 218, 255},
    {207, 218, 255},
    {205, 220, 255},
    {206, 220, 255},
    {207, 221, 255},
    {207, 221, 255},
    {208, 222, 255},
    {209, 223, 255},
    {210, 223, 255},
    {211, 224, 255},
    {212, 225, 255},
    {214, 225, 255},
    {215, 226, 255},
    {216, 227, 255},
    {217, 227, 255},
    {218, 229, 255},
    {220, 229, 255},
    {221, 230, 255},
    {222, 230, 255},
    {224, 231, 255},
    {225, 232, 255},
    {227, 233, 255},
    {228, 234, 255},
    {230, 235, 255},
    {231, 236, 255},
    {233, 237, 255},
    {235, 238, 255},
    {237, 239, 255},
    {239, 240, 255},
    {240, 241, 255},
    {243, 242, 255},
    {245, 243, 255},
    {247, 245, 255},
    {249, 246, 255},
    {252, 247, 255},
    {254, 249, 255},
    {255, 249, 253},
    {255, 248, 251},
    {255, 246, 247},
    {255, 245, 245},
    {255, 244, 242},
    {255, 243, 239},
    {255, 242, 236},
    {255, 240, 233},
    {255, 239, 230},
    {255, 238, 227},
    {255, 236, 224},
    {255, 235, 220},
    {255, 233, 217},
    {255, 232, 213},
    {255, 230, 210},
    {255, 228, 206},
    {255, 227, 202},
    {255, 225, 198},
    {255, 223, 194},
    {255, 221, 190},
    {255, 219, 186},
    {255, 217, 182},
    {255, 215, 177},
    {255, 213, 173},
    {255, 211, 168},
    {255, 209, 163},
    {255, 206, 159},
    {255, 204, 153},
    {255, 201, 148},
    {255, 199, 143},
    {255, 196, 137},
    {255, 193, 132},
    {255, 190, 126},
    {255, 187, 120},
    {255, 184, 114},
    {255, 180, 107},
    {255, 177, 101},
    {255, 173, 94},
    {255, 169, 87},
    {255, 165, 79},
    {255, 161, 72},
    {255, 157, 63},
    {255, 152, 54},
    {255, 147, 44},
    {255, 142, 33},
    {255, 138, 18},
    {255, 131, 0},
    {255, 126, 0},
    {255, 121, 0},
    {255, 115, 0},
    {255, 109, 0},
    {255, 101, 0},
    {255, 93, 0},
    {255, 83, 0},
    {255, 71, 0},
    {255, 56, 0},
};

#define LIMIT 5e-5

RGB_Struct ConvertTemperatureToRGB(float temperature)
{
    uint16_t index = 0;

    if (temperature > 0)
      index = (uint16_t)((temperature + .25 - LIMIT) / .25);
    
    return TEMP_INDEX_TO_RGB_TABLE[index];
}

int main (void) {
  
  for (float temp = 0; temp <= 2; temp += .05) {
  
    RGB_Struct color = ConvertTemperatureToRGB(temp);
    
    printf ("temp: %.2f    R: %3" PRIu8 "  G: %3" PRIu8 "  B: %3" PRIu8 "\n",
            temp, color.Red, color.Green, color.Blue);
  }
}

(注意: 精确宽度类型的正确格式说明符可在 inttypes.h 中找到。对于 uint8_t,作为无符号值的输出使用PRIu8。本质上等同于hhu。关于这一点有很多问题和答案可以参考)

上面的代码只是为 02 摄氏度之间的温度生成 RGB 值,增量为 .05,因此您可以判断 index 的处理值。您可以根据需要进行测试、微调和调整。

另请注意,如评论中所述,您确实应该将生成的最大索引值限制为 table 中的有效索引。您可以通过确保 index 的值按​​ table 中元素的数量减少模数来做到这一点,例如如果不是零情况,那么您可以使用 index = index % NELEM; 在 return 中强制使用有效索引(我不确定您可以更改多少代码——我会留给您如果您可以进行这些更改 - 请注意 NELEM% 一起使用时的类型)在 table 下方,您可以将 NELEM 定义为:

#define NELEM sizeof TEMP_INDEX_TO_RGB_TABLE / sizeof *TEMP_INDEX_TO_RGB_TABLE

如果您确实想将 index 限制为 table 中的有效索引。

检查一下,如果您还有其他问题,请告诉我。