6.4 離散的コサイン変換 (DCT : discrete cosine transform ) (1)DCTとは DFTの式 が偶関数であれば,DFTの式の虚数項を0として
DCTの解釈 半周期分が与えられたものとして, 偶関数になるように拡張し (Sin成分,すなわち虚数項=0) 周期的に接続したDFTとみなすことができる。
(2)偶関数への拡張の方法 ①軸のところを中心とみなす方法 ②軸から0.5ずれたところで折り返す方法 ① n = 0 を中心として偶関数に拡張 元の信号 ① n = -0.5 を中心として偶関数に拡張
軸から0.5ずらす場合の接続方法も2種類 ①周期2N-1として接続 ②周期2Nとして接続(第Ⅱ種DCTで採用) ①周期2N-1として周期的に接続 ②周期2Nとして周期的に接続
(3)DCTの種類 偶関数への拡張方法,周期的な接続方法の違いにより,以下のような種類がある。
(4)第Ⅱ種DCT 第Ⅱ種は,JPEG,MPEGなど 画像処理で最もよく使われる方法 (逆変換)第Ⅲ種と同じ
VBAでの記述 ①データ宣言とパルス信号の設定 (色々な信号を設定してみよう) Private Const Num = 128 Private Const PI = 6.28318530717959 / 2 Private X(Num) As Double Private Y(Num) As Double Private Z(Num) As Double Private Sub パルス() For K = 0 To Num - 1 X(K) = -1 If K >= 30 And K < 80 Then X(K) = 1 Next X(Num) = X(0) End Sub
VBAでの記述 ②結果設定とボタンClickイベントハンドラ Private Sub 結果設定() With Worksheets("Sheet1") .Cells(1, 1) = "No.": .Cells(1, 2) = "X" .Cells(1, 3) = "Y": .Cells(1, 4) = "Z" For K = 0 To Num .Cells(K + 2, 1) = K: .Cells(K + 2, 2) = X(K) .Cells(K + 2, 3) = Y(K): .Cells(K + 2, 4) = Z(K) Next End With End Sub Sub ボタン1_Click() パルス DCT IDCT 結果設定
VBAでの記述 ③DCT Private Sub DCT() 'DCT(離散的コサイン変換) Dim C0 As Double: Dim Cn0 As Double C0 = 1 / Sqr(Num): Cn0 = Sqr(2#) * C0 For K = 0 To Num - 1 Y(K) = 0 For j = 0 To Num - 1 Y(K) = Y(K) + X(j) * Cos((2 * j + 1) * K * PI / (2 * Num)) Next If K = 0 Then Y(K) = C0 * Y(K) Else Y(K) = Cn0 * Y(K) End If Y(Num) = 0 End Sub
VBAでの記述 ④IDCT Private Sub IDCT() 'IDCT(離散的逆変換) Dim C0 As Double: Dim C As Double C0 = 1# / Sqr(2#): C = Sqr(2# / Num) For j = 0 To Num - 1 Z(j) = C0 * Y(0) For K = 1 To Num - 1 Z(j) = Z(j) + Y(K) * Cos((2 * j + 1) * K * PI / (2 * Num)) Next Z(j) = C * Z(j) Z(Num) = Z(0) End Sub
DCTの結果
色々なDCTの結果(1)
色々なDCTの結果(2)
(5)高速DCT(Chenのアルゴリズム) FFTを使ってDCTを効率よく実行することも可能。 ここでは,Chenのアルゴリズムを示す。 DCTはN=4のとき次のように行列式で表現できる。 これを小行列に分解し,因数分解することで計算量を減らす。
計算の手順 JPEG,MPEGで使われているN=8の場合
VBAでの記述 ①データ宣言とパルス信号の設定 Private Const Num = 8 Private Const PI = 3.12159265358979 Private X(Num) As Double '入力データ Private Y(Num) As Double '変換結果 Private Z(Num) As Double '逆変換結果 Private Sub パルス() For K = 0 To Num - 1 X(K) = -1 If K >= 3 And K <= 5 Then X(K) = 1 Next X(Num) = X(0) End Sub
VBAでの記述 ②結果設定とボタンのClickイベントハンドラ Private Sub 結果設定() With Worksheets("Sheet2") .Cells(1, 1) = "No.": .Cells(1, 2) = "X" .Cells(1, 3) = "Y": .Cells(1, 4) = "Z" For K = 0 To Num .Cells(K + 2, 1) = K: .Cells(K + 2, 2) = X(K) .Cells(K + 2, 3) = Y(K): .Cells(K + 2, 4) = Z(K) Next End With End Sub Sub Sheet2_ボタン1_Click() パルス FDCT IDCT 結果設定
VBAでの記述 ③Chenのアルゴリズム(その1) Private Sub FDCT() 'FDCT(Chenのアルゴリズム) '(既に入力XがYに複写されているものとする) Cos4 = Cos(PI / 4): Cos8 = Cos(PI / 8) Cos16 = Cos(PI / 16): Cos163 = Cos(3 * PI / 16) Sin8 = Sin(PI / 8): Sin16 = Sin(PI / 16) Sin163 = Sin(3 * PI / 16) For J = 0 To Num Y(J) = X(J) Next For J = 0 To 3 tmp = Y(J) + Y(7 - J): Y(7 - J) = Y(J) - Y(7 - J): Y(J) = tmp tmp = Y(0) + Y(3): Y(3) = Y(0) - Y(3): Y(0) = tmp tmp = Y(1) + Y(2): Y(2) = Y(1) - Y(2): Y(1) = tmp tmp = Cos4 * (-Y(5) + Y(6)) Y(6) = Cos4 * (Y(5) + Y(6)) Y(5) = tmp
VBAでの記述 ④Chenのアルゴリズム(その2) tmp = Cos4 * (Y(0) + Y(1)) Y(1) = Cos4 * (Y(0) - Y(1)) Y(0) = tmp tmp = Sin8 * Y(2) + Cos8 * Y(3) Y(3) = -Cos8 * Y(2) + Sin8 * Y(3) Y(2) = tmp tmp = Y(4) + Y(5): Y(5) = Y(4) - Y(5): Y(4) = tmp tmp = -Y(6) + Y(7) Y(7) = Y(6) + Y(7) Y(6) = tmp tmp = Sin16 * Y(4) + Cos16 * Y(7) Y(7) = -Cos16 * Y(4) + Sin16 * Y(7) Y(4) = tmp
VBAでの記述 ⑤Chenのアルゴリズム(その3) tmp = Cos163 * Y(5) + Sin163 * Y(6) Y(6) = -Sin163 * Y(5) + Cos163 * Y(6) Y(5) = tmp tmp = Y(1): Y(1) = Y(4): Y(4) = tmp tmp = Y(3): Y(3) = Y(6): Y(6) = tmp For J = 0 To Num - 1 Y(J) = 0.5 * Y(J) Next Y(Num) = Y(0) End Sub
VBAでの記述 ⑥確認用逆変換 Private Sub IDCT() 'IDT(離散的逆変換) Dim C0 As Double: Dim C As Double C0 = 1# / Sqr(2#): C = Sqr(2# / Num) For J = 0 To Num - 1 Z(J) = C0 * Y(0) For K = 1 To Num - 1 Z(J) = Z(J) + Y(K) * Cos((2 * J + 1) * K * PI / (2 * Num)) Next Z(J) = C * Z(J) Z(Num) = Z(0) End Sub
FDCTの結果
色々なFDCTの結果(1)
色々なFDCTの結果(2)