4

BMP 画像を JPEG に変換する C++ プログラムを作成しています。

私が従おうとしている基本的なアルゴリズムは次のとおりです。

  1. RGB カラー スペースを Y、Cb、Cr に変換します。
  2. Cb と Cr を 2 ずつダウンサンプリングします (つまり、2*2 の正方形ブロックごとに 4 つの異なる Y 値がありますが、1 つの Cb と 1 つの Cr 値があります)。
  3. 各 8*8 ピクセルのデータ単位に DCT を適用します...
  4. 次に、Cb と Cr の標準量子化テーブルを使用して、DCT 係数に量子化を適用します。
  5. ジグザグに並べます。
  6. ハフマン符号化を使用して DC 係数と AC 係数を別々に符号化します。
  7. 適切なヘッダーを書き込み、ハフマンでエンコードされた値をファイルに書き込みます...

上記を正しく実行していることを確認しましたが、まだ次の問題があります。

  • 生成中の JPEG が正しく表示されません。
  • 色の値 R=10 B=10 および G=100 で完全に満たされた小さな 8*8 24 ビット (色深度) の bmp ファイルを作成しました... 64 ピクセルすべてが同じ色です..
  • 私がすべてのステップで取得しているデータは次のとおりです...
    • BMP ヘッダー サイズ 40
    • ヘッダーのサイズ 40
    • 幅8
    • 高さ8
    • 飛行機の数 1
    • ピクセルあたりのビット数 24
    • 画像サイズ 194
    • x 解像度 1 メートルあたりのピクセル数 2834
    • 1 メートルあたりの y 解像度ピクセル 2834
    • 色数 0
    • インプ色の数 0
    • (R,B,G)=(10,10,100) の Y Cb Cr 変換は (62,-29,-37) です。

では、まず Y 成分について考えてみましょう。

Y 成分の DCT 係数は次のとおりです。

 495 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0

量子化の後、私が取得している単一のデータ単位のジグザグ順序は、Y コンポーネントの場合です。

30 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0

上記のジグザグ配列のハフマンコーディングは次のとおりです。

  • Y DC コーディング: 00111110
  • Y ac コーディング: 1010 (ac ハフマン テーブル (輝度 Y) EOB 値は 1010 の場合)
  • 同様に、Cb および Cr コンポーネントのハフマン コーディングは次のとおりです。
  • cb dc コーディング: 11000010
  • cb ac コーディング: 01 (ac ハフマン テーブル (クロミナンス Cb,Cr) の場合、EOB 値は 01)
  • CR DC コーディング: 110101110
  • cr ac コーディング: 01
  • 私が得る最終的なハフマンコードは次のとおりです。

    001111101010110000100111010111001 長さ 33

そのため、8 で割り切れるように、1 のパディングが行われます。

0011111010101100001001110101110011111111 Length 40.

ここで、個々の 0 または 1 は、実際には JPEG ファイルにそのまま保存する必要があるビットですが、ビットごとにファイルに書き込むことができないため、合計 8 ビットが取得され、基数の整数値に変換されます。 10 となり、1 バイト文字に格納されます。

私が間違っている場所について誰か提案を提供できますか?

4

2 に答える 2

2

問題を解決するために最初に行うことは、JPEG標準でPennebaker/Mitchelの本を入手することです。

操作の順序は次のとおりです。

1)色空間変換2)FDCT 3)量子化4)ジグザグ並べ替え5)ハフマンエンコード

あなたが従わなければならない多くの規則のために、それらの操作は多くの複雑さを持っています。

a)DC予測子を適切に処理していますか?b)ゼロの実行でA / Cコンポーネントを適切にエンコードしていますか?c)「パッド入りゼロ」とマーカーに関する出力ストリームルールを尊重していますか?d)色空間変換式は正しいですか?各コンポーネントから差し引く必要のある0x80が含まれていますか?e)サブサンプリングオプションの選択に基づいて、MCUブロックを適切な順序でエンコードしていますか?

于 2009-07-19T21:27:06.767 に答える
-2

車輪を再発明しないでください。これを行うには、ImageMagick、Magick++、または CImg を使用します。

于 2009-07-19T22:20:01.810 に答える