YCoCg24
這裏是一個顏色的變換我稱之爲「YCoCg24」這三個八位整數(代表紅色,綠色和藍色分量)轉換成其他三個八位(簽字)整數(代表類似的Y'CbCr顏色空間),並且是雙射(因此可以在不丟失信息)被反轉:
G R B Y Cg Co
| | | | | |
| |->-(-1)->(+) (+)<-(-/2)<-| |
| | | | | |
| (+)<-(/2)-<-| |->-(+1)->(+) |
| | | | | |
|->-(-1)->(+) | | (+)<-(-/2)<-|
| | | | | |
(+)<-(/2)-<-| | | |->-(+1)->(+)
| | | | | |
Y Cg Co G R B
forward transformation reverse transformation
或在僞代碼:
function forward_lift(x, y):
signed int8 diff = (y - x) mod 0x100
average = (x + (diff >> 1)) mod 0x100
return (average, diff)
function reverse_lift(average, signed int8 diff):
x = (average - (diff >> 1)) mod 0x100
y = (x + diff) mod 0x100
return (x, y)
function RGB_to_YCoCg24(red, green, blue):
(temp, Co) = forward_lift(red, blue)
(Y, Cg) = forward_lift(green, temp)
return(Y, Cg, Co)
function YCoCg24_to_RGB(Y, Cg, Co):
(green, temp) = reverse_lift(Y, Cg)
(red, blue) = reverse_lift(temp, Co)
return(red, green, blue)
種
一些示例顏色:
color R G B Y CoCg24
white 0xFFFFFF 0xFF0000
light grey 0xEFEFEF 0xEF0000
dark grey 0x111111 0x110000
black 0x000000 0x000000
red 0xFF0000 0xFF01FF
lime 0x00FF00 0xFF0001
blue 0x0000FF 0xFFFFFF
G,R-G,B-G色彩空間
另一個顏色變換的三個8位整數轉換成其他三個八位整數。
function RGB_to_GCbCr(red, green, blue):
Cb = (blue - green) mod 0x100
Cr = (red - green) mod 0x100
return(green, Cb, Cr)
function GCbCr_to_RGB(Y, Cg, Co):
blue = (Cb + green) mod 0x100
red = (Cr + green) mod 0x100
return(red, green, blue)
一些示例顏色:
color R G B G CbCr
white 0xFFFFFF 0xFF0000
light grey 0xEFEFEF 0xEF0000
dark grey 0x111111 0x110000
black 0x000000 0x000000
評論
似乎有不少lossless color space transforms。 Henrique S. Malvar等人提到了幾種無損色彩空間變換。"Lifting-based reversible color transformations for image compression"; JPEG XR有無損色空間轉換; 在幾個「lossless JPEG」提案中使用的原始可逆顏色變換(ORCT); G,R-G,B-G色彩空間; 等 Malvar等人對24位RGB像素的26位YCoCg-R表示看起來很興奮。
但是,它們幾乎全部都需要超過24位來存儲轉換後的像素顏色。
我在YCoCg24中使用的「lifting」技術類似於Malvar等人的技術,也涉及JPEG XR中的無損色彩空間轉換。
由於加法是可逆的(和加法模0x100的是雙射),任何從變換(A,B)到(X,Y),其可以通過以下Feistel network來製造是可逆的,並且雙射:
a b
| |
|->-F->-(+)
| |
(+)-<-G-<-|
| |
x y
其中(+)表示8位加法(模數0x100),abxy都是8位值,F和G表示任意函數。
細節
爲什麼你只需要3個字節來存儲結果嗎? 這聽起來像是反作用的premature optimization。 如果您的目標是在合理的時間內將圖像無損壓縮成儘可能小的壓縮文件,那麼中間階段的大小就無關緊要。它可能會適得其反 - 「較大」的中間表示(例如可逆顏色變換或26位YCoCg-R)可能會導致較小的最終壓縮文件大小比「較小」的中間表示(例如RGB或YCoCg24)。編輯: Oopsies。 「(x)mod 0x100」或「(x)& 0xff」中的任一個給出完全相同的結果 - 我想要的結果。 但不知何故,我把它們混雜在一起產生了一些不起作用的東西。
謝謝你的詳細解答。 24位要求的原因是實用的。我知道使用26位中間階段可以提高壓縮比(事實上,有多箇中間階段會增加流的大小)。但是,我使用的算法對單個字節進行操作,而不是位。通過將比特流視爲字節流,它將失去顏色空間變換引入的優良屬性。 – Ruud
是的,無論何時將系統從字節流切換到位流,系統通常需要運行8次左右才能運行,而且調試起來要困難得多。所以我同情你的願望,如果可能的話,堅持使用字節流。 –
大衛,這是一個非常酷的轉變。非常感謝提供它。有一件事要注意,你的reverse_lift應該返回x和y,而不是平均值和差值。 – MoDJ