【RGB=HSI】Single-chip microcomputer control RGB single lamp and HSI conversion algorithm

Recently, I am working on a gadget for RGB fill light. There is an OLED screen on the project to display the HSI parameters of the current light. I am completely unfamiliar with HSI. Due to the tight schedule and heavy tasks, I didn’t even think about going to Baidu to find out what HSI is. , directly took the sample to test a set of parameters, and calculated a HSI-to-RGB function by myself. Although it took a lot of time, there is still a little error. The error is mainly a matter of range. The range of RGB should be 0-255. When I calculated, I set the range to 0-100 for the convenience of calculation, and the final result is considered good.

But when RGB was converted to HSI, there was no time to calculate, so I remembered to ask a big guy around me, only then did I know what the HSI color model is, and I also popularized this mutual conversion algorithm for me. I optimize the use, and record the optimized C language writing here, and casually refer to the introduction of HSI in Encyclopedia to deepen understanding.

The HSI [Hue-Saturation-Intensity (Lightness), HSI or HSL] color model uses H, S, and I three parameters to describe the color characteristics, where H defines the frequency of the color, called hue; S represents the depth of the color, called saturation degree ; I means intensity or brightness.

The H component in the HSI color model is the main factor to determine the color. When it changes, the hue value will also change; the larger the S component (close to 1), the purer the color, and the smaller the S component (close to 0), the closer the color pure gray

 

 

 C language code implementation:

/**
     * HSV -> RGB.
     * @param hue Hue.In the range[0..360]
     * @param saturation Saturation. In the range[0..100].
     * @param value Value. In the range[0..100].
     * @return RGB color space. In the range[0..255].
     */
u8 *HSVtoRGB(u16 h, u16 s, u16 i)
{
    static u8 rgb[3] = {0};
    float hue = (float)h;
    float saturation = (float)(s/100.0);
    float value = (float)(i/100.0);
    float hi= (float)((u32)(hue / 60.0) % 6);
    float f = (float)((hue / 60.0) - (u32)(hue / 60.0));
    float p = (float)(value * (1.0 - saturation));
    float q = (float)(value * (1.0 - (f * saturation)));
    float t = (float)(value * (1.0 - ((1.0 - f) * saturation)));

    if (hi == 0){
        rgb[0] = (int)(value * 255);
        rgb[1] = (int)(t * 255);
        rgb[2] = (int)(p * 255);
    }
    else if (hi == 1){
        rgb[0] = (int)(q * 255);
        rgb[1] = (int)(value * 255);
        rgb[2] = (int)(p * 255);
    }
    else if (hi == 2){
        rgb[0] = (int)(p * 255);
        rgb[1] = (int)(value * 255);
        rgb[2] = (int)(t * 255);
    }
    else if (hi == 3){
        rgb[0] = (int)(p * 255);
        rgb[2] = (int)(value * 255);
        rgb[1] = (int)(q * 255);
    }
    else if (hi == 4){
        rgb[0] = (int)(t * 255);
        rgb[2] = (int)(value * 255);
        rgb[1] = (int)(p * 255);
    }
    else if (hi == 5){
        rgb[0] = (int)(value * 255);
        rgb[1] = (int)(p * 255);
        rgb[2] = (int)(q * 255);
    }
    return rgb;
}

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
/**
 * RGB -> HSV.
 * Adds (hue + 360) % 360 for represent hue in the range [0..359].
 * @param red Red coefficient. Values in the range [0..255].
 * @param green Green coefficient. Values in the range [0..255].
 * @param blue Blue coefficient. Values in the range [0..255].
 * @return HSV color space.
 */
int *RGBtoHSV(u16 r, u16 g, u16 b)
{
    static int hsv[3] = {0};
    int max = MAX(r,MAX(g,b));
    int min = MIN(r,MIN(g,b));
    int delta = max - min;

    // Hue
    if (max == min){
        hsv[0] = 0;
    }
    else if (max == r){
        hsv[0] = (60*(g - b) / delta);
    }
    else if (max == g){
        hsv[0] = (60*(b - r) / delta) + 120;
    }
    else if (max == b){
        hsv[0] = (60*(r - g) / delta) + 240;
    }
    if(hsv[0] < 0) {
       hsv[0] += 360;
    }
    // Saturation
    if (delta == 0)
        hsv[1] = 0;
    else
        hsv[1] = (100*delta/ max);

    //Value
    hsv[2] = 100*max/255;
    return hsv;
}

Finally, let me explain that there are indeed a lot of information about the HSI algorithm model on the Internet. This is just a small demand for single-light switching, so I didn’t spend too much time organizing it. I just realized the simplest function, and my The project’s handling of float is not so friendly. When passing parameters, they are converted to integer processing. When the conversion results of some specific values ​​are tested, there will be a little error. Here, I would like to ask the big guys from all walks of life if there is a better optimization method. Or code implementation.

Guess you like

Origin blog.csdn.net/Main_BUG/article/details/124703456