【RGB=HSI】シングルチップマイコン制御RGBシングルランプとHSI変換アルゴリズム

最近、RGB フィルライト用のガジェットに取り組んでいます。プロジェクトには、現在のライトの HSI パラメータを表示するための OLED スクリーンがあります。私は HSI にまったく慣れていません。タイトなスケジュールと重いタスクのために、私は知りませんでした」 HSI とは何かを知るために Baidu に行くことさえ考えていません.サンプルを直接取得して一連のパラメーターをテストし、HSI-to-RGB 関数を自分で計算しました.多くの時間がかかりましたが,まだあります.誤差はほとんどありません. 誤差は主に範囲の問題です. RGB の範囲は 0-255 である必要があります. 計算するときは, 計算の便宜上範囲を 0-100 に設定しました.最終結果は良いと見なされます.

しかし、RGB を HSI に変換するときは、計算する時間がなかったので、周りの偉い人に聞いてみたのを思い出し、HSI カラー モデルが何であるかを知り、この相互変換アルゴリズムを普及させました。使用を最適化し、最適化された C 言語の記述をここに記録し、エンサイクロペディアの HSI の紹介をさりげなく参照して理解を深めてください。

HSI [Hue-Saturation-Intensity (Lightness)、HSI または HSL] カラー モデルは、H、S、および I の 3 つのパラメータを使用して色特性を記述します。ここで、H は色相と呼ばれる色の頻度を定義し、S は色の深さを表します。彩度と呼ばれる色; 私は強度または明るさを意味します.

HSIカラーモデルのH成分は色を決定する主な要因であり、これが変化すると色相値も変化し、S成分が大きいほど(1に近いほど)色が純粋になり、S成分が小さいほど(0 に近い)、ピュア グレーに近い色

 

 

 C 言語コードの実装:

/**
     * 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;
}

最後に、HSI アルゴリズム モデルに関する情報は、インターネット上に実際にたくさんあることを説明させてください. これは、単一光スイッチングに対する小さな需要にすぎないため、整理するのにあまり時間をかけませんでした.最も単純な関数であり、私のプロジェクトの浮動小数点数の扱いはあまり友好的ではありません. パラメータを渡すときに、それらは整数処理に変換されます. 特定の値の変換結果をテストすると、少しエラーが発生します. ここで, 私はより良い最適化方法、またはコードの実装があるかどうか、あらゆる分野の大物に尋ねるのが好きです。

おすすめ

転載: blog.csdn.net/Main_BUG/article/details/124703456