YCoCg24
Hier ist eine Farbtransformation I „YCoCg24“ nenne, dass die drei Acht-Bit-Ganzzahl umwandelt (repräsentierte Rot-, Grün- und Blau-Komponenten) in drei andere acht Bit (Vorzeichen) ganze Zahlen (repräsentierte ein Farbraum ähnlich wie Y'CbCr) und bijektiv ist (und daher kann ohne Informationsverlust umgekehrt werden):
G R B Y Cg Co
| | | | | |
| |->-(-1)->(+) (+)<-(-/2)<-| |
| | | | | |
| (+)<-(/2)-<-| |->-(+1)->(+) |
| | | | | |
|->-(-1)->(+) | | (+)<-(-/2)<-|
| | | | | |
(+)<-(/2)-<-| | | |->-(+1)->(+)
| | | | | |
Y Cg Co G R B
forward transformation reverse transformation
oder in Pseudo-Code:
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)
Einige Beispiel-Farben:
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-Farbraum
Eine andere Farbtransformation, die drei Acht-Bit-Integer in drei anderen acht-Bit-Integer umwandelt.
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)
Einige Beispiel-Farben:
color R G B G CbCr
white 0xFFFFFF 0xFF0000
light grey 0xEFEFEF 0xEF0000
dark grey 0x111111 0x110000
black 0x000000 0x000000
Kommentare
Es scheint schon einige lossless color space transforms zu sein. Mehrere verlustfreie Farbraumtransformationen werden in Henrique S. Malvar, et al."Lifting-based reversible color transformations for image compression"; gibt es die verlustfreie Farbraumtransformation in JPEG XR; die ursprüngliche reversible Farbtransformation (ORCT), die in verschiedenen "lossless JPEG" Vorschlägen verwendet wird; G-, R-G-, B-G-Farbraum; usw. Malvar und andere scheinen ziemlich begeistert von der 26-Bit-YCoCg-R-Darstellung eines 24-Bit-RGB-Pixels zu sein.
Fast alle von ihnen erfordern jedoch mehr als 24 Bits, um die umgewandelte Pixelfarbe zu speichern.
Die Technik "lifting", die ich in YCoCg24 verwende, ähnelt der in Malvar et al. Und der verlustfreien Farbraumtransformation in JPEG XR.
Da zusätzlich umkehrbar (und Addition modulo 0x100 bijektiv), jede Transformation von (a, b) zu (x, y), die durch die folgende Feistel network hergestellt werden können, ist reversibel und bijektive:
a b
| |
|->-F->-(+)
| |
(+)-<-G-<-|
| |
x y
wobei (+) eine 8-Bit-Addition (Modulo 0x100), Abxy alle 8-Bit-Werte und F und G eine beliebige Funktion angeben.
Details
Warum haben Sie nur 3 Bytes in das Ergebnis zu speichern? Das klingt nach einem kontraproduktiven premature optimization. Wenn es Ihr Ziel ist, ein Bild in einer möglichst kleinen komprimierten Datei verlustfrei zu komprimieren, ist die Größe der Zwischenstufen irrelevant. Es kann sogar kontraproduktiv sein - eine "größere" Zwischendarstellung (wie Reversible Color Transformation oder der 26-Bit-YCoCg-R) kann in kleinere endgültige komprimierte Dateigröße als eine "kleinere" Zwischendarstellung (wie z RGB oder YCoCg24).
EDIT: Oopsies. Entweder eines von "(x) mod 0x100" oder "(x) & 0xff" geben genau die gleichen Ergebnisse - die Ergebnisse, die ich wollte. Aber irgendwie habe ich sie zusammengewürfelt, um etwas zu produzieren, das nicht funktionieren würde.
Vielen Dank für diese ausführliche Antwort. Der Grund für die 24-Bit-Anforderung ist ein praktischer. Ich verstehe, dass das Arbeiten mit einer 26-Bit-Zwischenstufe das Komprimierungsverhältnis verbessern kann (tatsächlich gab es mehrere Zwischenstufen, die die Größe des Stroms erhöhten). Der Algorithmus, den ich verwendete, arbeitet jedoch auf einzelnen Bytes, nicht auf Bits. Wenn der Bitstrom als Byte-Stream behandelt wird, verliert er die schönen Eigenschaften, die durch die Farbraum-Transformation entstehen. – Ruud
Ja, jedes Mal, wenn ich ein System von einem Byte-Stream in einen Bit-Stream umschalte, dauert das System normalerweise etwa 8 mal so lange und ist viel schwieriger zu debuggen. Ich habe also Verständnis dafür, dass Sie möglichst bei Byte-Streams bleiben wollen. –
David, das ist eine sehr coole Transformation. Vielen Dank für die Bereitstellung. Eine Sache zu beachten, sollte Ihr reverse_lift X und Y, nicht Durchschnitt und Diff zurückgeben. – MoDJ