2012-03-12 3 views
4

私は、特異値分解を使用して特定のイメージを圧縮しようとしています。私は、私はそれがプロセス全体に見えるゴミ色のピクセルを取得し続けていることに気づくまで私はそれを持っていると思った。イメージを圧縮しようとするとカラーピクセルが表示される(写真が含まれます)

Garbage pixels

右上に示される番号は0がオリジナル画像である反復の数を示します。

これはよくあるエラーですか?私は行方不明のものがありますか?

私はそれが私の数学、それ自体と関係しているかもしれないと考えます。私はJAMAを使用しています。JAMAは、これを処理するJavaの行列パッケージです。以下は各反復のための私の実装です:

for (int i = 0; i < k; i++) {  
    Matrix step = (uColumns[i].times(sValues[i])).times(vColumns[i].transpose()); 
    encoded = encoded.plus(step); 
} 

基本的に私がやって(または実行しようとしている)だものです:

M = M + (s1*u1*v1^t) 

は私の実装と明らかに何か問題があるのか​​、おそらく誤りでありますJAMAがSVDを実行する方法のために?私がテストしたところから、行列UとVの値の符号は、WolframalphaまたはMatlabによって生成された値と行によって異なります。

何か助けていただければ幸いです。

おかげで、

Justian

+0

私はこのライブラリをSVDのために知りません。私はC#でこのライブラリを使用していましたが、この種のプログラムをJavaで使ったことはありませんでしたが、類似の圧縮方法を使用する他のユーザーとあなたの結果を比較しましたか? – HericDenis

+0

オーバーフローまたはアンダーフローによって白いピクセルが発生する可能性がありますか?たとえば、最初は黒(0)だったピクセルは、非可逆圧縮のために-0.01になり、-1に丸められ、画面上では255になります... –

答えて

2

これあなたの写真は、原色に分解される:

Lena SVD decomposed to RGB

はどうやらあなたは間違った方法で色に数字と数字に色を変換しています。 RGBピクセルを単一の数値として扱い、それをSVD数値処理に渡しますが、実際にRGBであるという情報は失われます。

ほとんどの損失のある画像圧縮方法は、重要性の低いビットを破棄することによって圧縮を達成しています。しかし、RGBが単一のの場合、各R、G、Bの重要度の低いビットは重要度の高いビットでインターリーブされます。ピクセルを単一の数値として渡すとき、この情報は失われ、SVD手順は、重要度の低いRビットを有意性の高いGビットよりも有意に解釈し、すべてのGビットおよびBビットを完全に破棄しようとする可能性があるRビットの後に格納される。

たとえば、明るい灰色のピクセル(192,192,192)は、RGB値が0xC0C0C0です。この値を1%の誤差で圧縮すると、たとえば0xC2AE32が得られます。圧縮アルゴリズムの観点からは、この値はほとんど目立たないオリジナルよりわずか1%だけ大きい値です。しかしこれをRGBに変換すると、(194,174,50)となります。 R成分は実際にはほとんど同じですが、GとBは壊れています。これは、プログラムの "ガベージカラー"のソースです。分解された画像は、R成分が正しく圧縮され、G成分が高圧縮レベルでランダムノイズになり、B成分が常にランダムであることを示す。

暗い領域に散在する単一の明るいピクセルです。これらは明らかに数字のオーバーフローとアンダーフローが原因です。たとえば、黒のピクセル(0,0,0)は0x000000 = 0としてエンコードされます。ロッシー圧縮は、正または負の小さな誤差を導入し、-1 = 0xFFFFFFFFを生成することができます。 RGBでは(255,255,255)になります。

どうすればよいですか?

SVDイメージの圧縮をテストしているだけでグレースケールイメージを使用するだけであれば、RGB値の下位バイトを0から255の範囲にするだけです。これに対応して、結果を表示すると出力ファイルを書き込むか、この値をグレースケールとして解釈するか、0x010101を掛けてRGB値全体を取得します。

カラーイメージを圧縮する必要がある場合は、R、G、BコンポーネントでSVDアルゴリズムを個別に実行する必要があります。色を扱う最も簡単な方法ですが、最も効率的な方法はありません。より高い圧縮率と目立たないアーチファクトを得るには、RGBからLab(輝度と2つのクロミナンスチャネル)に変換する方が良いです。クロミナンスをもっと圧縮することができます。これがJPEGの仕組みです。

イメージを伸張するとき、SVDから値を計算した後で、スクリーンに表示するか、ファイルに書き込む前に、すべての結果値(R、G、B)を0-255の範囲でクランプします。これにより、散在した白い点が除去されます。

関連する問題