Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

離散コサイン変換

DCT 定義

離散コサイン変換 (DCT) は、さまざまな大きさと周波数からなる正弦波の和として、イメージを表現します。関数 dct2 は、イメージの 2 次元離散コサイン変換 (DCT) を計算します。DCT は、標準のイメージについて、視覚的に重要な情報のほとんどが、DCT の数個の係数に集中しているという性質をもっています。このため、DCT はイメージ圧縮の用途にしばしば使用されます。たとえば、DCT は、JPEG として知られている国際標準の非可逆イメージ圧縮アルゴリズムで中心的な機能を果たしています (この名前は、この標準を策定したワーキング グループの名前、Joint Photographic Experts Group に因んで付けられています)。

M 行 N 列の行列 A の 2 次元 DCT は、次のように定義されます。

Bpq=αpαqm=0M1n=0N1Amncosπ(2m+1)p2Mcosπ(2n+1)q2N,0pM10qN1αp={1/M,2/M,p=01pM1αq={1/N,2/N,q=01qN1

Bpq の値は A"DCT 係数" と呼ばれています (MATLAB® の行列インデックスは、0 からでなく 1 から始まります。このため、MATLAB の行列の要素 A(1,1) および B(1,1) は、数学上の量としては A00 および B00 に対応します)。

DCT は、逆変換も可能で、次の式で表せます。

Amn=p=0M1q=0N1αpαqBpqcosπ(2m+1)p2Mcosπ(2n+1)q2N,0mM10nN1αp={1/M,2/M,p=01pM1αq={1/N,2/N,q=01qN1

逆 DCT 方程式は、任意の M 行 N 列の行列 A が、

αpαqcosπ(2m+1)p2Mcosπ(2n+1)q2N,   0pM10qN1

形式の関数 MN の和として記述できることを意味するものとして解釈できます。

これらの関数は、DCT の "基本関数" と呼ばれます。このため、DCT 係数 Bpq は、各基底関数に適用された "重み" と見なすことができます。8 行 8 列の行列に対して、64 個の基本関数が、このイメージにより示されます。

8 行 8 列の行列の 64 個の基本関数

64 basis functions are arranged in an 8-by-8 grid. As the row and column indices in the grid increase, the basis functions have higher vertical and horizontal frequencies, respectively.

水平周波数は左から右方向へ増加し、垂直周波数は上から下へ増加します。左上の定数値基底関数は、"DC 基底関数" と呼ばれ、対応する DCT 係数 B00 は、多くの場合 "DC 係数" と呼ばれます。

DCT 変換行列

Image Processing Toolbox™ ソフトウェアを使用して DCT を計算する方法は 2 つあります。最初の方法は、関数 dct2 を使用します。dct2 は、FFT ベースのアルゴリズムを使用して、大きな入力を高速で処理できます。2 番目の方法は、DCT "変換行列" を使う方法です。この行列は、関数 dctmtx から出力され、小さい正方行列、たとえば、8 行 8 列や 16 行 16 列の行列に対しては、非常に効率的なものです。M 行 M 列の変換行列 T は、次のように表すことができます。

Tpq={1M2Mcosπ(2q+1)p2Mp=0,1pM1,0qM10qM1

M 行 M 列の行列 A に対して、T*A は、A の各列の 1 次元の DCT を各列に含む M 行 M 列の行列になります。A の 2 次元の DCT は、B=T*A*T' として計算できます。T が実数直交行列なので、その逆はその転置と同じものになります。そのため、B の 2 次元逆 DCT は、T'*B*T で与えられます。

離散コサイン変換を使用したイメージ変換

この例では、離散コサイン変換 (DCT) を使用してイメージを圧縮する方法を説明します。この例は、入力イメージの 8 行 8 列のブロックの 2 次元 DCT を計算し、各ブロックにある 64 の DCT 係数のうち 10 個以外のすべてを 0 に置き換えます。そして、各ブロックの 2 次元逆 DCT を使用して、イメージを再構成します。この例は変換行列の計算法を使用しています。

DCT は JPEG イメージ圧縮アルゴリズムで使用されます。入力イメージは 8 行 8 列または 16 行 16 列のブロックに分割され、各ブロックの 2 次元 DCT が計算されます。DCT 係数は、続いて量子化、暗号化されて送信されます。JPEG レシーバ (または、JPEG ファイル リーダー) は、量子化した DCT 係数を復号し、各ブロックの 2 次元逆 DCT を計算し、その結果を集めて 1 つのイメージを作成します。一般的なイメージでは、DCT 係数の多くは、ほとんどゼロに近い値になります。これらの係数は再構成後のイメージの質に大きな影響を与えないので、切り捨てることができます。

イメージをワークスペースに読み取って double クラスに変換します。

I = imread('cameraman.tif');
I = im2double(I);

イメージ内にある 8 行 8 列のブロックの 2 次元 DCT を計算します。関数 dctmtx は N 行 N 列の DCT 変換行列を返します。

T = dctmtx(8);
dct = @(block_struct) T * block_struct.data * T';
B = blockproc(I,[8 8],dct);

各ブロックにある 64 の DCT 係数のうち 10 個以外のすべてを切り捨てます。

mask = [1   1   1   1   0   0   0   0
        1   1   1   0   0   0   0   0
        1   1   0   0   0   0   0   0
        1   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];
B2 = blockproc(B,[8 8],@(block_struct) mask .* block_struct.data);

各ブロックの 2 次元逆 DCT を使用してイメージを再構成します。

invdct = @(block_struct) T' * block_struct.data * T;
I2 = blockproc(B2,[8 8],invdct);

元のイメージと再構成後のイメージを左右に並べて表示します。再構成イメージに質的な低下が見られますが、DCT 係数の約 85% を切り捨てたにもかかわらず、はっきりとイメージを認識できます。

imshow(I)

figure
imshow(I2)