Chuyển đổi RGB sang thang độ xám / cường độ


128

Khi chuyển đổi từ RGB sang thang độ xám, người ta nói rằng các trọng số cụ thể cho các kênh R, G và B nên được áp dụng. Các trọng số này là: 0,2989, 0,5870, 0,1140.

Người ta nói rằng lý do cho điều này là nhận thức / cảm giác khác nhau của con người đối với ba màu sắc này. Đôi khi người ta cũng nói đây là những giá trị được sử dụng để tính toán tín hiệu NTSC.

Tuy nhiên, tôi đã không tìm thấy một tài liệu tham khảo tốt cho điều này trên web. Nguồn gốc của các giá trị này là gì?

Xem thêm những câu hỏi trước: ở đâyở đây .


26
Có nó làm. Tôi luôn lập trình trên các giá trị RGB. Áp dụng các giá trị "thế giới thực" cho các tính toán này là rất quan trọng nếu bạn muốn ứng dụng của mình xứng đáng với muối của nó.
Neil N

1
Nhiều lập trình viên có thể không quan tâm và tính toán các ảnh thang độ "sai", nhưng tôi thì có.
ypnos

6
Tôi đồng ý rằng nó liên quan đến mã hóa - chắc chắn là một vấn đề thú vị và có liên quan nếu bạn đang mã hóa đồ họa. +1 như tôi muốn biết câu trả lời cho mình
Cruachan

6
RGB lập trình liên quan. Đó là lập trình liên quan như phân tích chuỗi ngày. Khi chuyển đổi văn bản "true" thành giá trị boolean.
Neil N

Câu trả lời:


87

Các số cụ thể trong câu hỏi là từ CCIR 601 (xem liên kết Wikipedia bên dưới).

Nếu bạn chuyển đổi RGB -> thang độ xám với các số khác nhau / các phương thức khác nhau, bạn sẽ không thấy nhiều sự khác biệt trên màn hình máy tính bình thường trong điều kiện ánh sáng bình thường - hãy thử.

Dưới đây là một số liên kết về màu sắc nói chung:

Wikipedia Luma

Trang web nổi bật của Bruce Lindbloom

chương 4 về màu sắc trong cuốn sách của Colin Ware, "Trực quan thông tin", isbn 1-55860-819-2; liên kết dài này đến Ware trong Books.google.com có thể hoặc không hoạt động

cambridgeincolor : "hướng dẫn tuyệt vời, được viết tốt về cách thu nhận, giải thích và xử lý ảnh kỹ thuật số bằng cách sử dụng phương pháp định hướng trực quan, nhấn mạnh khái niệm về thủ tục"

Nếu bạn chạy vào RGB "tuyến tính" và "phi tuyến", đây là một phần của một ghi chú cũ đối với tôi về điều này. Lặp lại, trong thực tế, bạn sẽ không thấy nhiều sự khác biệt.


RGB -> ^ gamma -> Y -> L *

Trong khoa học màu sắc, các giá trị RGB phổ biến, như trong html rgb (10%, 20%, 30%), được gọi là "phi tuyến" hoặc Gamma được sửa . Giá trị "tuyến tính" được định nghĩa là

Rlin = R^gamma,  Glin = G^gamma,  Blin = B^gamma

trong đó gamma là 2.2 cho nhiều PC. RGB thông thường đôi khi được viết là R 'G' B '(R' = Rlin ^ (1 / gamma)) (nhấp chuột thuần túy) nhưng ở đây tôi sẽ bỏ '.

Độ sáng trên màn hình CRT tỷ lệ thuận với RGBlin = RGB ^ gamma, do đó, 50% màu xám trên CRT khá tối: .5 ^ 2.2 = 22% độ sáng tối đa. (Màn hình LCD phức tạp hơn; hơn nữa, một số card đồ họa bù cho gamma.)

Để lấy số đo độ sáng được gọi L*từ RGB, trước tiên hãy chia RGB cho 255 và tính toán

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma

Đây là Ytrong không gian màu XYZ; nó là thước đo màu "độ chói". (Các công thức thực không chính xác là x ^ gamma, nhưng đóng; gắn với x ^ gamma cho lần đầu tiên.)

Cuối cùng,

L* = 116 * Y ^ 1/3 - 16

"... khao khát sự đồng nhất về nhận thức [và] rất phù hợp với nhận thức của con người về sự nhẹ nhàng." - Không gian màu Wikipedia Lab


8
Y = 0,2126 * R + 0,7152 * G + 0,0722 * B - Wikipedia ( en.wikipedia.org/wiki/Grayscale )
iamantony

14

Tôi thấy rằng ấn phẩm này được tham chiếu trong một câu trả lời cho một câu hỏi tương tự trước đó. Nó rất hữu ích:

http://cadik.posevete.cz/color_to_gray_ev Assessment /

Nó cho thấy 'tấn' các phương pháp khác nhau để tạo ra các ảnh thang độ xám với các kết quả khác nhau!


9

Đây là một số mã trong c để chuyển đổi rgb sang thang độ xám. Trọng số thực được sử dụng cho chuyển đổi rgb sang thang độ xám là 0,3R + 0,6G + 0,11B. những trọng lượng này hoàn toàn không quan trọng để bạn có thể chơi với chúng. Tôi đã làm cho chúng 0,25R + 0,5G + 0,25B. Nó tạo ra một hình ảnh tối hơn một chút.

LƯU Ý: Đoạn mã sau giả định định dạng pixel xRGB 32 bit

unsigned int *pntrBWImage=(unsigned int*)..data pointer..;  //assumes 4*width*height bytes with 32 bits i.e. 4 bytes per pixel
unsigned int fourBytes;
        unsigned char r,g,b;
        for (int index=0;index<width*height;index++)
        {
            fourBytes=pntrBWImage[index];//caches 4 bytes at a time
            r=(fourBytes>>16);
            g=(fourBytes>>8);
            b=fourBytes;

            I_Out[index] = (r >>2)+ (g>>1) + (b>>2); //This runs in 0.00065s on my pc and produces slightly darker results
            //I_Out[index]=((unsigned int)(r+g+b))/3;     //This runs in 0.0011s on my pc and produces a pure average
        }

2
0,3 0,6 0,11 không thêm vào 1. Wikipedia dường như đề xuất 0,30 0,59 0,11.
damix911

Đúng, nhưng kết quả duy nhất của việc họ không thêm vào 1 sẽ là một sự thay đổi rất nhỏ về cường độ. Phương pháp đề xuất 0,25,0,5,0.25 không thêm vào 1 nhưng sẽ không thành vấn đề nếu không. Đó là một sự tối ưu hóa vì vậy việc từ bỏ một chút chính xác là một sự đánh đổi hợp lý.
twerdster

2
@twerdster Cả hai hệ số đều không đúng. .3, .6, .11 là tiêu chuẩn NTSC cũ, không phải sRGB / Rec709 (đó là những gì web và hầu hết các máy tính sử dụng). Và 0,25,0,5,0,25 của bạn không phải là một sự đánh đổi hợp lý - B chỉ là 7% độ chói, bạn đã sai bởi 347%. Các hệ số cho sRGB / r709 (sau khi tuyến tính hóa): Rlin * 0.2126 + Glin * 0.7152 + Blin * 0.0722 = Y Các trọng số phổ này có nguồn gốc từ nhận thức phổ của con người. Bạn không thể chỉ kẹt bất cứ con số nào bạn muốn để thuận tiện và hy vọng là chính xác. Bạn cần tuyến tính hóa sRGB và sau đó áp dụng các hệ số chính xác.
Myndex

Nếu bạn đang ở trong một tình huống mà sự phân chia quá đắt đỏ, một phép tính gần đúng sử dụng một phép nhân với các ca và thêm là : 0.11111111 * ((G + (G<<1) + R) <<1) + B). Điều này tương đương với (2*R+6*G+B) / 9)hoặc 0.222 R + 0.666 G + 0.111 B. Trước khi đi vào sản xuất, so sánh với một công thức chính xác cho các trường hợp thử nghiệm khác nhau.
ToolmakerSteve


6

Kiểm tra Câu hỏi thường gặp về màu sắc để biết thông tin về điều này. Các giá trị này đến từ việc tiêu chuẩn hóa các giá trị RGB mà chúng tôi sử dụng trong màn hình của mình. Trên thực tế, theo Câu hỏi thường gặp về Màu sắc, các giá trị bạn đang sử dụng đã lỗi thời, vì chúng là các giá trị được sử dụng cho tiêu chuẩn NTSC gốc và không phải là màn hình hiện đại.


3

Nguồn gốc của các giá trị này là gì?

"Nguồn" của các hệ số được đăng là các thông số kỹ thuật NTSC có thể thấy trong Rec601Đặc điểm của Truyền hình .

"Nguồn cuối cùng" là các thí nghiệm CIE vào khoảng năm 1931 về nhận thức màu sắc của con người. Phản ứng phổ của tầm nhìn của con người không đồng nhất. Các thí nghiệm đã dẫn đến trọng số của các giá trị tristimulus dựa trên nhận thức. Các nón L, M và S 1 của chúng tôi rất nhạy cảm với các bước sóng ánh sáng mà chúng tôi xác định là "Đỏ", "Xanh lục" và "Xanh lam" (tương ứng), đó là nơi bắt nguồn của các màu chính của tristimulus. 2

Ánh sáng tuyến tính 3 trọng số phổ cho sRGB (và Rec709) là:

R lin * 0.2126 + G lin * 0.7152 + B lin * 0.0722 = Y

Chúng dành riêng cho không gian màu sRGB và Rec709, được dùng để đại diện cho màn hình máy tính (sRGB) hoặc màn hình HDTV (Rec709) và được trình bày chi tiết trong các tài liệu ITU cho Rec709 và cả BT.2380-2 (10/2018)

BÓNG ĐÁ (1) Nón là các tế bào phát hiện màu của võng mạc mắt.
(2) Tuy nhiên, các bước sóng tristimulus được chọn KHÔNG ở "đỉnh" của từng loại hình nón - thay vào đó các giá trị tristimulus được chọn sao cho chúng kích thích trên loại hình nón cụ thể hơn nhiều so với loại khác, tức là tách kích thích.
(3) Bạn cần tuyến tính hóa các giá trị sRGB của mình trước khi áp dụng các hệ số. Tôi thảo luận điều này trong một câu trả lời khác ở đây.


-2

Những giá trị này thay đổi từ người này sang người khác, đặc biệt là đối với những người bị mù màu.


-4

là tất cả những điều này thực sự cần thiết, nhận thức của con người và CRT so với LCD sẽ khác nhau, nhưng cường độ RGB thì không, Tại sao không L = (R + G + B)/3và đặt RGB mới thành L, L, L?


3
Đơn giản là trung bình cả ba nguyên thủy R, G, B coi chúng là bằng nhau về mặt nhận thức, đó không phải là trường hợp của hệ thống thị giác của con người.
Bill Feth
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.