2016-10-28 15 views
2

私はこれを知っていますhas already been askedしかし、そこに与えられたanwserは動作しません。数時間かけて数式やアルゴリズムを探しましたが、何も見つかりませんでした。その結果、RGBをRGBWに変換する独自のアルゴリズムを、最も効率的な方法で作成し始めました。私が扱ってる色はなく、他の場合では、原色である場合、それは正常に動作しますRGBをRGBWに変換する

 //'Ri', 'Gi', and 'Bi' correspond to the Red, Green, and Blue inputs. 
     var M = Math.Max(Ri, Math.Max(Gi, Bi)); //The maximum value between R,G, and B. 
     int Wo =0; //White output 
     int Ro=0; //Red output 
     int Go=0; //Green output 
     int Bo=0; //Blue output 

     int av = 0; //Average between the two minimum values 
     int hR = 0; //Red with 100% hue 
     int hG = 0; //Green with 100% hue 
     int hB = 0; //Blue with 100% hue 

     //These 4 lines serve to figure out what the input color is with 100% hue. 
     float multiplier = 255.0f/M; 
     hR = Convert.ToInt32(Ri * multiplier); 
     hG = Convert.ToInt32(Gi * multiplier); 
     hB = Convert.ToInt32(Bi * multiplier); 

     //Depending on the maximum value, get an average of the least used colors, weighted for their importance in the overall hue. 
     //This is the problematic part 
     if (M == Ri) 
      av = (Bi*hB + Gi*hG)/(hB+hG); 
     else if (M == Gi) 
      av = (Ri*hR + Bi*hB)/(hR+hB); 
     else if (M == Bi) 
      av = (Gi*hG + Ri*hR)/(hG+hR); 

     //Set the rgbw colors 
     Wo = av; 
     Bo = Bi - av; 
     Ro = Ri - av; 
     Go = Gi - av; 
     if (Wo < 1) Wo = 0; 
     if (Bo < 1) Bo = 0; 
     if (Ro < 1) Ro = 0; 
     if (Go < 1) Go = 0; 
     if (Wo > 255) Wo = 255; 
     if (Bo > 255) Bo = 255; 
     if (Ro > 255) Ro = 255; 
     if (Go > 255) Go = 255; 

:これは私が現在持っているものです。何がどこでもうまくいくでしょうか?私は正しい軌道にいますか?

編集:ここには、私が取り組んでいる問題の.gifがあります。あなたがここで整数の分割を行っている

if (M == Ri) 
     av = (Bi*hB + Gi*hG)/(hB+hG); 
    else if (M == Gi) 
     av = (Ri*hR + Bi*hB)/(hR+hB); 
    else if (M == Bi) 
     av = (Gi*hG + Ri*hR)/(hG+hR); 

:RGBW値は、私は、問題はここにあると思いずっと下 enter image description here

+2

整数の除算が問題の一部であるのだろうかと思います。倍数を浮動小数点数にして最終値を切り捨てたいのではないですか? – shawnt00

+1

「うまくいかない」とはどういう意味ですか? –

+0

@ shawnt00そうは思わない。私は.NETがそれを扱っていると確信しています。倍精度浮動小数点数で割って整数に変換しても同じ結果が得られますが、同じ結果が得られます。 – user2950509

答えて

4

私は最終的にRGBをRGBWに変換する方法を考え出しました。完全に間違った:

//Get the maximum between R, G, and B 
float tM = Math.Max(Ri, Math.Max(Gi, Bi)); 

//If the maximum value is 0, immediately return pure black. 
if(tM == 0) 
    { return new rgbwcolor() { r = 0, g = 0, b = 0, w = 0 }; } 

//This section serves to figure out what the color with 100% hue is 
float multiplier = 255.0f/tM; 
float hR = Ri * multiplier; 
float hG = Gi * multiplier; 
float hB = Bi * multiplier; 

//This calculates the Whiteness (not strictly speaking Luminance) of the color 
float M = Math.Max(hR, Math.Max(hG, hB)); 
float m = Math.Min(hR, Math.Min(hG, hB)); 
float Luminance = ((M + m)/2.0f - 127.5f) * (255.0f/127.5f)/multiplier; 

//Calculate the output values 
int Wo = Convert.ToInt32(Luminance); 
int Bo = Convert.ToInt32(Bi - Luminance); 
int Ro = Convert.ToInt32(Ri - Luminance); 
int Go = Convert.ToInt32(Gi - Luminance); 

//Trim them so that they are all between 0 and 255 
if (Wo < 0) Wo = 0; 
if (Bo < 0) Bo = 0; 
if (Ro < 0) Ro = 0; 
if (Go < 0) Go = 0; 
if (Wo > 255) Wo = 255; 
if (Bo > 255) Bo = 255; 
if (Ro > 255) Ro = 255; 
if (Go > 255) Go = 255; 
return new rgbwcolor() { r = Ro, g = Go, b = Bo, w = Wo }; 

enter image description here

任意の最適化のアイデアは歓迎以上です:)

1

です。すべての変数は整数なので、除算は整数除算になります。

if (M == Ri) 
     av = (int)((float)(Bi*hB + Gi*hG)/(hB+hG)); 
    else if (M == Gi) 
     av = (int)((float)(Ri*hR + Bi*hB)/(hR+hB)); 
    else if (M == Bi) 
     av = (int)((float)(Gi*hG + Ri*hR)/(hG+hR)); 

これは浮動小数点除算を行い、必要な答えを得るはずです。あなたはまだ丸めエラーがあるかも知れません。その場合、floatからdoubleに変更してください。

が浮かぶように乗数の計算を変更する:

float multiplier = 255.0/M; 

は半分だけの問題に対処し、今、あなたのテストとして、他の合併症を引き起こし:

if (M == Ri) 
else if (M == Gi) 
else if (M == Bi) 

は今、これまでに真ではないようです。テストに丸め誤差要因を追加する必要があります。 epsilonが適して小さな値である

if (Math.Abs(M - Ri) < epsilon) 
else if (Math.Abs(M - Gi) < epsilon) 
else if (Math.Abs(M - Bi) < epsilon) 

(通常、私は10E-6をお勧めしたい、しかし、あなたが試すことができます。

また、MはRGBあなたドン値のいずれかに十分に近接していない場合'tはavに設定されています - これは常に0に設定されたままです。これは、すべてが黒で表示されている結果をも提供します

+0

固定されていて、まだ何もありません。私はかなりの問題は私が使用している実際のロジックから来ていると確信しています。ターコイズを飽和/不飽和化しようとすると何が起こるかを見ると、0にする必要があるとき255の白の出力が得られます(完全に飽和したターコイズの白はありません)。私は青を飽和/不飽和状態にしたときのように動作するはずです。 – user2950509

0

私はここで少しオフになる場合もありますが、エレクトロニクス・エンジニアとして、私は、軽いし、コードのXDをoutputingのLEDを参照してください。とにかく白を出力するには、すべてのRGBまたは白のチャンネルを "点灯"させますが、同じ輝度(LEDの井戸は私の視点からの井戸)を維持して、4つのチャンネルすべてを混合して、チャネル。 これは現時点では問題ではないと思われますが、後で参考になるかもしれません。

+0

しかし、もし私が非常に高いCRI白を持っていれば、RGBチャンネルをフルにしても光の質は低下しませんか? – user2950509

関連する問題