2013-09-30 39 views
10

Tôi có đoạn mã sau:Phạm vi tọa độ trong không gian màu CIELAB là gì?

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

Đoạn quan trọng (*) là thế này:

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

có thêm một pixel với thành phần của nó thu nhỏ lại để dao động [0, 1] để được tiếp tục sử dụng trong phân loại nhiệm vụ với các trình phân loại khác nhau. Một số người trong số họ yêu cầu các thuộc tính được bình thường hóa như thế này, những người khác không quan tâm - do đó chức năng này.

Tuy nhiên, tôi nên làm gì khi tôi muốn phân loại pixel trong một không gian màu khác với RGB, như L*a*b*? Trong khi giá trị của tất cả các tọa độ trong không gian màu RGB rơi vào khoảng [0,256) trong L*a*b* không gian màu a*b* được cho là không bị chặn.

Vì vậy, khi thay đổi phần phân đoạn (*) tới:

Lab lab = c.ToLab(); 

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

(ToLab là một phương pháp mở rộng, triển khai sử dụng các thuật toán thích hợp từ here)

những gì tôi nên đặt cho dấu hỏi?

+0

Câu hỏi thú vị. Hãy nhớ rằng câu trả lời phụ thuộc vào lựa chọn rgb và màu trắng tham chiếu. Phương pháp tiếp cận vũ lực do BartoszKP đề xuất phụ thuộc vào các yếu tố này và có thể cần phải chạy lại tùy theo nền tảng. – SeF

Trả lời

21

Trong thực tế, số lượng tất cả có thể là RGB màu là hữu hạn, do đó, không gian L*a*b* bị chặn. Rất dễ dàng để tìm phạm vi tọa độ với chương trình đơn giản sau đây:

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); 

hoặc cách tương tự bằng bất kỳ ngôn ngữ nào khác.

Vì vậy, CIELAB không gian phối hợp dãy như sau:

L trong [0, 100]

Một trong [-86,185, 98.254]

B trong [-107,863, 94,482 ]

và câu trả lời 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

Xác định RGB. sRGB? Adobe RGB? –

+0

@ColeJohnson Điểm rất thú vị. Tôi cho rằng điều này làm việc cho bất kỳ phiên bản cụ thể của RGB, nhưng tôi không chắc chắn. Ở đây ngữ cảnh được định nghĩa là GDI + và trong bất kỳ ngôn ngữ nào khác làm thư viện đồ họa của ngôn ngữ này. – BartoszKP

+0

FWIW Không gian CIELAB bao gồm các màu 'tưởng tượng' theo thiết kế: http://en.wikipedia.org/wiki/Lab_color_space – theodox

8

Thông thường, các giá trị sau làm việc bởi vì nó là sản phẩm tiêu chuẩn của thuật toán chuyển đổi màu sắc phổ biến:

  • L * trục (nhẹ nhàng) dao động từ 0 đến 100

  • a * và b * phạm vi trục (thuộc tính màu) từ -128 đến +127

Thông tin khác có thể tìm thấy here.

0

Nếu mã Lab chuyển đổi được thực hiện phù hợp với các phòng thí nghiệm-màu sắc nét (xem, ví dụ Lab color space), sau đó hoạt động f(...), được sử dụng để xác định L, ab thay đổi trong vòng [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] 

Bình thường hóa các giá trị này trong phạm vi mà biến byte có thể giữ. Vì vậy, bạn phải phân tích mã để xác định, phạm vi nó tạo ra. Nhưng một lần nữa, các công thức trong Wiki sẽ cung cấp cho bạn phạm vi ở trên. Cùng một phạm vi sẽ cung cấp cho bạn code here

+0

Cảm ơn câu trả lời của bạn. IIRC Tôi đã sử dụng các thuật toán chuyển đổi chính xác từ trang web EasyRGB mà bạn đang đề cập đến (RGB -> XYZ -> LAB) và kết quả khác nhau - bạn có chắc chắn các giá trị bạn cung cấp là chính xác không? – BartoszKP

Các vấn đề liên quan