2013-09-30 2 views
10

я следующий кусок кода:Каковы диапазоны координат в цветовом пространстве 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; 
} 

Ключевой фрагмент (*) это:

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

который добавляет пиксель с его компонентами масштабируется в диапазоне [0, 1] для дальнейшего использования в классификации задачи с разными классификаторами. Некоторые из них требуют, чтобы атрибуты были нормализованы таким образом, другим это не волнует - отсюда и эта функция.

Однако, что мне делать, если я хотел бы классифицировать пиксели в другом цветовом пространстве, чем RGB, например L*a*b*? Хотя значения всех координат в цветовом пространстве 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 диапазоны являются следующие:

л в [0, 100]

А в [-86,185, 98,254] ​​

B в [-107.863, 94.482 ]

и ответ:

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

  • а * и б * (цветовые атрибуты) оси в диапазоне от -128 до +127

Более подробную информацию можно найти here.

0

Если код Lab-преобразование выполняется в соответствии с определением Lab-цветов (см, например, Lab color space), то функция f(...), которая используется для определения L, a и b изменения в пределах [4/29,1 ], 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

Смежные вопросы