我想无损压缩图像,以便采取规律性的优势,我想将图像从RGB转换成Y'CbCr的。 (我的意思通过RGB和Y'CbCr的具体细节在这里并不重要; RGB数据由三个字节组成,和我有三个字节来存储结果)。
转换过程本身是非常简单的,但是有一个问题:虽然转型是数学可逆的,在实践中会出现舍入误差。 当然,这些错误是小,几乎无法察觉,但它确实意味着过程没有任何无损多。
我的问题是:转换存在,即转换三八位整数(代表红,绿,蓝组件)到其他三个八位整数(代表色彩空间类似的Y'CbCr,其中两个部件只是稍微改变与关于位置,或者至少比在RGB色彩空间)更小,并且可以在不丢失信息被反转?
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,RG,BG彩色空间
另一种颜色的变换三个八位整数转换成其他三个八位整数。
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.马尔瓦等人提及。 “基于提升的可逆的颜色变换的图像压缩” ; 有一个在无损色彩空间转换JPEG XR ; 原始可逆的颜色变换(ORCT)在几个“使用无损JPEG ”建议; G,RG,BG彩色空间; 等马尔瓦等人似乎非常兴奋的24位RGB像素的26位YCoCg中-R表示。
然而,几乎所有的人都需要超过24位存储变换后的像素颜色。
的“ 提升 ”技术我在YCoCg24使用类似于一个在马尔瓦等人,并在JPEG XR无损色彩空间变换。
因为除了是可逆的(和加法模0x100的是双射), 任何从变换(A,B)到(X,Y),其可以通过以下来生产的Feistel网络是可逆的,并且双射:
a b
| |
|->-F->-(+)
| |
(+)-<-G-<-|
| |
x y
其中,(+)表示8位加法(模为0x100),ABXY都是8位值,和F和G指示的任意功能。
细节
为什么你只需要3个字节来存储结果吗? 这听起来像一个反效果过早的优化 。 如果你的目标是在合理的时间量无损压缩的图像到尽可能小的压缩文件成为可能,那么中间阶段的大小是无关紧要的。 它甚至可以是适得其反 - “较大”的中间表示(诸如可逆的颜色变换或26位YCoCg中-R)可能导致比“较小”的中间表示较小的最终压缩文件大小(例如,RGB或YCoCg24)。
编辑:Oopsies。 无论是“(X)MOD 0x100的”或一个“(X)为0xFF”给完全相同的结果 - 我想要的结果。 但不知何故,我混杂在一起,以产生的东西,是行不通的。
我没有找到一个这样的解决方案,使用JPEG 2000年它被称为可逆的颜色变换(RCT),它在被描述维基百科还有JPEG网站 (虽然四舍五入方法并不一致)。 结果不作为与不可逆的颜色变换一样好,但是。
我还发现,在改进可逆整数到整数变换颜色由秀昌沛建林俊鼎论文中描述一个更好的方法。 然而,在论文中描述的方法,并且通过JPEG 2000所使用的方法,需要额外的位来存储结果。 这意味着,转换后的值不适合在24位了。