问题描述
我正在尝试无损压缩图像,并且为了利用规则性,我想将图像从RGB转换为Y'CbCr. (我在这里所说的RGB和Y'CbCr的确切细节并不重要; RGB数据由三个字节组成,我有三个字节用于存储结果.)
I am trying to losslessly compress an image, and in order to take advantage of regularities, I want to convert the image from RGB to Y'CbCr. (The exact details of what I mean by RGB and Y'CbCr are not important here; the RGB data consists of three bytes, and I have three bytes to store the result in.)
转换过程本身非常简单,但是存在一个问题:尽管转换在数学上是可逆的,但实际上会存在舍入误差.当然,这些错误很小,几乎看不到,但这确实意味着该过程不再是无损的.
The conversion process itself is pretty straightforward, but there is one problem: although the transformation is mathematically invertible, in practice there will be rounding errors. Of course these errors are small and virtually unnoticeable, but it does mean that the process is not lossless any more.
我的问题是:是否存在转换,将三个八位整数(代表红色,绿色和蓝色分量)转换为其他三个八位整数(代表类似于Y'CbCr的色彩空间,其中两个分量发生了变化)相对于位置而言仅略微改变,或者至少比RGB色彩空间中的位置要小),并且可以在不损失信息的情况下将其反转?
My question is: does a transformation exist, that converts three eight-bit integers (representing red, green and blue components) into three other eight-bit integers (representing a colour space similar to Y'CbCr, where two components change only slightly with respect to position, or at least less than in an RGB colour space), and that can be inverted without loss of information?
推荐答案
YCoCg24
这是我称为"YCoCg24"的一种颜色转换,它将三个八位整数(代表红色,绿色和蓝色分量)转换为其他三个八位(有符号)整数(代表类似于Y'CbCr的色彩空间) ),并且是双射的(因此可以求逆,而不会丢失信息):
Here is one color transformation I call "YCoCg24" that that converts three eight-bit integers (representing red, green and blue components) into three other eight-bit (signed) integers (representing a colour space similar to Y'CbCr), and is bijective (and therefore can be inversed without loss of information):
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颜色空间
另一种颜色转换,可将三个八位整数转换为其他三个八位整数.
Another color transformation that converts three eight-bit integers into three other eight-bit integers.
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
评论
似乎有很多无损颜色空间变换.Henrique S. Malvar等人提到了几种无损色彩空间转换. >基于提升的图像压缩可逆颜色转换" ; JPEG XR 中有无损色彩空间转换;几个""提案;G,R-G,B-G色彩空间;等等.Malvar等人似乎对24位RGB像素的26位YCoCg-R表示感到非常兴奋.
There seem to be quite a few lossless color space transforms.Several lossless color space transforms are mentioned in Henrique S. Malvar, et al. "Lifting-based reversible color transformations for image compression";there's the lossless colorspace transformation in JPEG XR;the original reversible color transform (ORCT) used in several "lossless JPEG" proposals;G, R-G, B-G color space;etc.Malvar et al seem pretty excited about the 26-bit YCoCg-R representation of a 24-bit RGB pixel.
但是,几乎所有像素都需要超过24位来存储转换后的像素颜色.
However, nearly all of them require more than 24 bits to store the transformed pixel color.
我在YCoCg24中使用的"提升"技术与Malvar等人的技术类似以及JPEG XR中的无损色彩空间转换.
The "lifting" technique I use in YCoCg24 is similar to the one in Malvar et al and to the lossless colorspace transformation in JPEG XR.
因为加法是可逆的(并且加法模0x100是双射的),所以任何转换都可以由(a,b)转换为(x,y),可由以下 Feistel网络具有可逆性和双向性:
Because addition is reversible (and addition modulo 0x100 is bijective), any transform from (a,b) to (x,y) that can be produced by the following Feistel network is reversible and bijective:
a b
| |
|->-F->-(+)
| |
(+)-<-G-<-|
| |
x y
其中(+)表示8位加法(模0x100),a b x y均为8位值,F和G表示任意函数.
where (+) indicates 8-bit addition (modulo 0x100), a b x y are all 8-bit values, and F and G indicate any arbitrary function.
详细信息
为什么只用3个字节来存储结果?听起来像是适得其反的过早优化.如果您的目标是在合理的时间内将映像无损压缩为尽可能小的压缩文件,则中间阶段的大小无关紧要.甚至可能适得其反-与较小"中间表示(例如RGB或YCoCg24)相比,较大"中间表示(例如可逆颜色转换或26位YCoCg-R)可能会导致最终压缩文件的大小更小.
Why do you only have 3 bytes to store the result in?That sounds like a counter-productive premature optimization.If your goal is to losslessly compress an image into as small a compressed file as possible in a reasonable amount of time, then the size of the intermediate stages is irrelevant.It may even be counter-productive --a "larger" intermediate representation (such as Reversible Colour Transform or the 26-bit YCoCg-R) may result in smaller final compressed file size than a "smaller" intermediate representation (such as RGB or YCoCg24).
糟透了.(x)mod 0x100"或(x)& 0xff"之一都给出完全相同的结果-我想要的结果.但是我不知何故把它们弄混了,产生了一些行不通的东西.
Oopsies.Either one of "(x) mod 0x100" or "(x) & 0xff" give exactly the same results --the results I wanted.But somehow I jumbled them together to produce something that wouldn't work.
这篇关于无损RGB到Y'CbCr的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!