9

画像をロスレス圧縮しようとしていますが、規則性を利用するために、画像をRGBからY'CbCrに変換したいと思います。(ここでは、RGBとY'CbCrの意味の正確な詳細は重要ではありません。RGBデータは3バイトで構成され、結果を格納するために3バイトがあります。)

変換プロセス自体は非常に簡単ですが、1つの問題があります。変換は数学的に可逆ですが、実際には丸め誤差が発生します。もちろん、これらのエラーは小さく、事実上目立たないものですが、それはプロセスがもはやロスレスではないことを意味します。

私の質問は、3つの8ビット整数(赤、緑、青のコンポーネントを表す)を他の3つの8ビット整数(Y'CbCrに似た色空間を表す)に変換する変換が存在するかどうかです。位置に関して、または少なくともRGB色空間よりも少ない)、そしてそれは情報を失うことなく反転することができますか?

4

2 に答える 2

16

YCoCg24

これは、私が「YCoCg24」と呼ぶ 1 つの色変換で、3 つの 8 ビット整数 (赤、緑、青の成分を表す) を 3 つの他の 8 ビット (符号付き) 整数 (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 色空間

3 つの 8 ビット整数を別の 3 つの 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

コメント

無損失色空間変換がかなりあるようです。Henrique S. Malvar, et al. では、いくつかの無損失色空間変換について言及されています。「画像圧縮のためのリフティングベースの可逆的な色変換」 ; JPEG XRには可逆色空間変換があります。いくつかの「ロスレス JPEG」提案で使用されている元の可逆色変換 (ORCT) 。G、RG、BG 色空間。Malvar らは、24 ビット RGB ピクセルの 26 ビット YCoCg-R 表現にかなり興奮しているようです。

ただし、それらのほとんどすべては、変換されたピクセルの色を格納するために 24 ビット以上を必要とします。

私が YCoCg24 で使用する「リフティング」技術は、Malvar らのものや JPEG XR の無損失色空間変換に似ています。

足し算は可逆 (そして 0x100 を法とする足し算は全単射) であるため、次のFeistel ネットワークで生成できる (a,b) から (x,y) への変換可逆かつ全単射です。

 a        b
 |        |
 |->-F->-(+)
 |        |
(+)-<-G-<-|
 |        |
 x        y

ここで、(+) は 8 ビット加算 (モジュロ 0x100) を示し、abxy はすべて 8 ビット値であり、F と G は任意の関数を示します。

詳細

結果を格納するのに 3 バイトしかないのはなぜですか? それは非生産的な時期尚早の最適化のように聞こえます。妥当な時間内に画像を可逆圧縮してできるだけ小さな圧縮ファイルにすることが目標である場合、中間段階のサイズは関係ありません。逆効果になることさえあります。「大きい」中間表現 (Reversible Color Transform や 26 ビット YCoCg-R など) は、「小さい」中間表現 (RGB やYCoCg24)。

編集:おっと。「(x) mod 0x100」または「(x) & 0xff」のどちらを使用しても、まったく同じ結果が得られます。これは私が望んでいた結果です。しかし、どういうわけか私はそれらをごちゃまぜにして、うまくいかないものを作りました.

于 2012-08-27T17:06:52.327 に答える
2

JPEG 2000 で使用されているそのようなソリューションを 1 つ見つけました。これはリバーシブル カラー変換 (RCT) と呼ばれ、WikipediaJPEG サイトで説明されています(ただし、丸め方法は一貫していません)。ただし、結果は不可逆色変換ほど良くはありません。

Soo-Chang Pei と Jian-Jiun Ding による論文「Improved Reversible Integer-to-integer Color Transforms 」で説明されているより良い方法も見つけました。ただし、その論文で説明されている方法、および JPEG 2000 で使用されている方法では、結果を格納するために余分なビットが必要です。これは、変換された値が 24 ビットに収まらないことを意味します。

于 2012-05-12T22:47:49.630 に答える