2013-09-30 13 views
10

Iは、次のコードを持っている:CIELAB色空間の座標範囲はどのくらいですか?

public List<Tuple<double, double, double>> GetNormalizedPixels(Bitmap image) 
{ 
    System.Drawing.Imaging.BitmapData data = image.LockBits(
     new Rectangle(0, 0, image.Width, image.Height), 
     System.Drawing.Imaging.ImageLockMode.ReadOnly, 
     image.PixelFormat); 

    int pixelSize = Image.GetPixelFormatSize(image.PixelFormat)/8; 

    var result = new List<Tuple<double, double, double>>(); 

    unsafe 
    { 
     for (int y = 0; y < data.Height; ++y) 
     { 
      byte* row = (byte*)data.Scan0 + (y * data.Stride); 

      for (int x = 0; x < data.Width; ++x) 
      { 
       Color c = Color.FromArgb(
        row[x * pixelSize + 3], 
        row[x * pixelSize + 2], 
        row[x * pixelSize + 1], 
        row[x * pixelSize]); 

       // (*) 
       result.Add(Tuple.Create(
        1.0 * c.R/255, 
        1.0 * c.G/255, 
        1.0 * c.B/255); 
      } 
     } 
    } 

    image.UnlockBits(data); 

    return result; 
} 

キー断片(*)は、このです:

さらに分類に使用する [0, 1]の範囲にスケーリングされ、その構成要素の画素を加算
result.Add(Tuple.Create(
    1.0 * c.R/255, 
    1.0 * c.G/255, 
    1.0 * c.B/255); 

異なる分類子を持つタスク。それらのうちのいくつかは、このように属性を正規化する必要があり、他の人は気にしません - したがって、この関数です。

L*a*b*のように、異なる色空間のピクセルをRGBよりも分類したい場合はどうすればよいですか? RGBの色空間におけるすべての座標の値は、範囲[0,256)にあり、L*a*b*の色空間a*b*は無制限と言われています。だから、

にフラグメント(*)を変更:

Lab lab = c.ToLab(); 

result.Add(Tuple.Create(
    1.0 * lab.L/100, 
    1.0 * lab.A/?, 
    1.0 * lab.B/?); 

ToLabは、拡張メソッドで、hereから適切なアルゴリズムを使用して実装)

私は疑問符のために何を置くべきですか?

+0

興味深い質問。答えはrgbの選択と参照の白に依存することを覚えておいてください。 BartoszKPが提案しているブルートフォースアプローチは、これらの要因に依存し、プラットフォームに応じて再実行する必要があるかもしれません。 – SeF

答えて

21

実際には、すべての可能なRGBの色の数は有限であるため、L*a*b*のスペースが制限されています。

Color c; 

double maxL = double.MinValue; 
double maxA = double.MinValue; 
double maxB = double.MinValue; 
double minL = double.MaxValue; 
double minA = double.MaxValue; 
double minB = double.MaxValue; 

for (int r = 0; r < 256; ++r) 
    for (int g = 0; g < 256; ++g) 
     for (int b = 0; b < 256; ++b) 
     { 
      c = Color.FromArgb(r, g, b); 

      Lab lab = c.ToLab(); 

      maxL = Math.Max(maxL, lab.L); 
      maxA = Math.Max(maxA, lab.A); 
      maxB = Math.Max(maxB, lab.B); 
      minL = Math.Min(minL, lab.L); 
      minA = Math.Min(minA, lab.A); 
      minB = Math.Min(minB, lab.B); 
     } 

Console.WriteLine("maxL = " + maxL + ", maxA = " + maxA + ", maxB = " + maxB); 
Console.WriteLine("minL = " + minL + ", minA = " + minA + ", minB = " + minB); 

または他の言語を使用した同様のものを使用すると、座標の範囲を簡単に見つけることができます。

したがって、CIELAB空間座標範囲は以下の通りである:[-107.863、94.482で[-86.185、98254]

B [0、100]

Aにおける

Lを]

と答えです:

Lab lab = c.ToLab(); 

result.Add(Tuple.Create(
    1.0 * lab.L/100, 
    1.0 * (lab.A + 86.185)/184.439, 
    1.0 * (lab.B + 107.863)/202.345); 
+4

RGBを定義します。 sRGB? Adobe RGB? –

+0

@ColeJohnson非常に興味深い点。私はこれがRGBの具体的なバージョンではうまくいくと主張しますが、わかりません。コンテキストはGDI +として定義され、この言語のグラフィックスライブラリとして他の言語で定義されます。 – BartoszKP

+0

FWIW CIELAB空間にはデザイン上の「架空の」色が含まれています:http://en.wikipedia.org/wiki/Lab_color_space – theodox

8

それは共通の色変換アルゴリズムの標準出力であるため、以下の値が動作通常、:

  • L *軸(明度)は、0から100

  • *及びbの範囲* -128から+127

それ以上(色属性)軸範囲情報がhere見出すことができます。

0

Labの変換コードは(例えばLab color spaceため、参照)ラボ・カラーの定義と一致して実装されている場合、[4/29,1内Lab変更を定義するために使用されるf(...)を、機能]、thefore

L = 116 * f(y) - 16 is in [0,100] 
a = 500 * (f(x)-f(y)) is in [-500*25/29, 500*25/29] 
b = 200 * (f(y)-f(z)) is in [-200*25/29, 200*25/29] 

(彼の返事でbortizjのような)一部の人々は、バイトの変数を保持することができ、これらの値が範囲に正規化します。そのため、コードを分析して、その範囲を決定する必要があります。しかし再び、Wikiの数式はあなたに上記の範囲を与えます。同じ範囲があなたに与えるでしょうcode here

+0

です。 IIRC私はあなたが参照しているEasyRGBウェブサイト(RGB→XYZ→LAB)から正確な変換アルゴリズムを使用していましたが、結果は異なります。 – BartoszKP

関連する問題