影像壓縮DCT_IDCT


靜態影像壓縮技術(分如下兩種)

無失真壓縮(Information Lossless):採用差值訊號編碼(DPCM , Differential PCM)
通常壓縮不到10倍,比方:TIFF 用於醫學影像,不可能用失真壓縮(會出人命)。

失真壓縮(Information Loss):採用離散餘弦轉換(DCT , Discrete Cosine Transform)
壓縮率極高,壓縮大概30倍但仍可獲得高品質,通常應用於網頁應用圖片呈現。
比方: JPEG


「JPEG標準」
是由「聯合攝影專家組」開發的損失式圖像壓縮標準,於1992年被正式接受為國際標準,採用基於DCT(離散餘弦變換)的變換編碼方法。

在JPEG壓縮中,圖像被視為在空間域中的i和j(或傳統上的x和y)的函數。

JPEG使用2D DCT作為壓縮過程中的一個步驟,以產生空間頻率域中的頻率響應,這個響應是由兩個整數u和v索引的函數F(u v)。

JPEG的DCT轉換編碼方法的有效性
基於三個層面來觀察會被推廣和使用如此成熟的原因

1.有用的圖像內容變化相對較慢:例如,在8×8的圖像塊內,像素強度值的變化通常不會出現快速且頻繁的變化,這表示圖像中存在「空間冗餘」。

2.人類對高空間頻率組件的損失不太敏感:心理物理學實驗表明,人們對於非常高空間頻率成分的損失不如低頻成分那麼容易察覺。因此,可以通過大幅減少高空間頻率成分來減少空間冗餘。

3.對於灰度(黑白)比彩色的視覺敏感度更高:因此,JPEG使用色度子採樣(4:2:0)。

JPEG壓縮流程
Step1.將圖像轉換為YIQ或YUV格式。
Step2.進行DCT變換。
Step3.量化DCT變換後的結果。
Step4.在量化後,圖像數據通過編碼表和熵編碼進行進一步處理。


主要流程圖如下

JPEG圖像壓縮的主要步驟
將RGB轉換為YIQ或YUV格式,並進行色彩子採樣。

對影像塊進行DCT(離散餘弦變換)。
  • 將每個圖像分割成8×8的塊,對每個塊進行2D DCT,輸出為每個塊的DCT係數F(u v)。
  • 使用塊的方法會使得每個塊與其鄰近上下文隔離,這就是為什麼當用戶指定高壓縮比時,JPEG圖像看起來會有“塊狀”(choppy)現象。

量化過程(量化公式如下) -> 量化步驟是JPEG壓縮中主要的損失來源。

F(u v)代表DCT係數,Q(u v)是量化矩陣的條目,^(,)代表量化後的DCT係數,將用於後續的熵編碼。


通過Zig-zag排序和行程長度編碼。
熵編碼。




以下是
針對影像亮度成分的量化表 和 色度量化表
表中的數值如下


JPEG壓縮過程涉及將影像分割成區塊,並對每個區塊進行單獨處理



針對平滑的影像取局部

矩陣Fˆ(u v)和f˜(i j)分別代表量化的DCT係數和經過逆DCT和反量化後重建的影像區塊


最終的差異矩陣(i j) = f(i j) − f˜(i j)顯示了原始塊和重建塊之間的差異,凸顯了JPEG壓縮的有損性質。





smooth的 dct及idct程式碼
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
original_block = [200 202 189 188 189 175 175 175; 200 203 198 188 189 182 178 175; 203 200 200 195 200 187 185 175; 200 200 200 200 197 187 187 187; 200 205 200 200 195 188 187 175; 200 200 200 200 200 190 187 175; 205 200 199 200 191 187 187 175; 210 200 200 200 188 185 187 186];

% 中心化影像區塊,藉由shift 128,使其範圍從0~255變成-128至127
centered_block = double(original_block) - 128;

%dct_block = dct2(original_block);
dct_block = dct2(centered_block);

% F(u; v) represents a DCT coecient
disp('DCT Coefficients F(u, v):');
disp(dct_block);


% 亮度量化表
luminance_quant_table = [16 11 10 16 24 40 51 61; 12 12 14 19 26 58 60 55; 14 13 16 24 40 57 69 56; 14 17 22 29 51 87 80 62; 18 22 37 56 68 109 103 77; 24 35 55 64 81 104 113 92; 49 64 78 87 103 121 120 101; 72 92 95 98 112 100 103 99];

quantized_dct = round(dct_block ./ luminance_quant_table);

% ^ F(u; v) represents the quantized DCT coecients
disp('Quantized DCT Coefficients ^F(u; v):');
disp(quantized_dct);


% 反量化
dequantized_dct = quantized_dct .* luminance_quant_table;
disp('dequantized_dct ~F(u; v):');
disp(dequantized_dct);

% 逆DCT
reconstructed_block = idct2(dequantized_dct);
% 反中心化
reconstructed_block = reconstructed_block + 128;

disp('Reconstructed Image Block ~f(i; j):');
disp(reconstructed_block);

% Compute the error matrix
error_matrix = original_block - reconstructed_block;
% Display the error matrix
disp('Error Matrix:');
disp(error_matrix);


預處理:首先,原始影像區塊的像素值通常會減去128(這在圖中標記為“Shifted by -128”)。這是因為在DCT(離散餘弦轉換)之前,通常需要對像素值進行中心化,使其範圍從0~255變為-128~127。這樣做可以提高DCT變換的數值穩定性。

DCT變換:接下來,對中心化後的資料應用二維DCT。 DCT變換將影像區塊從像素域(空間域)轉換到頻率域。 DCT能夠將影像資料中的能量集中到左上角(低頻部分),這使得高頻部分(右下角)的係數往往接近於0,以便於後續的量化和壓縮。

量化:DCT變換後,所得的係數矩陣將會被量化表(量化矩陣)Q(u, v)所量化。量化是透過將DCT係數矩陣的每個元素除以量化矩陣的對應元素並四捨五入到最近的整數來完成的。這個過程會導致資訊損失,是JPEG壓縮有損的主要原因。

量化後的DCT係數:量化後得到的係數矩陣F^(u, v)將會用於後續的編碼步驟,例如熵編碼。



最終完整程式加上error matrix結果計算和原始影像矩陣的誤差


textured的 dct及idct程式碼
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
%original_block = [200 202 189 188 189 175 175 175; 200 203 198 188 189 182 178 175; 203 200 200 195 200 187 185 175; 200 200 200 200 197 187 187 187; 200 205 200 200 195 188 187 175; 200 200 200 200 200 190 187 175; 205 200 199 200 191 187 187 175; 210 200 200 200 188 185 187 186];
original_block = [70 70 100 70 87 87 150 187; 85 100 96 79 87 154 87 113; 100 85 116 79 70 87 86 196; 136 69 87 200 79 71 117 96; 161 70 87 200 103 71 96 113; 161 123 147 133 113 113 85 161; 146 147 175 100 103 103 163 187; 156 146 189 70 113 161 163 197];


% 中心化影像區塊,藉由shift 128,使其範圍從0~255變成-128至127
centered_block = double(original_block) - 128;

%dct_block = dct2(original_block);
dct_block = dct2(centered_block);

% F(u; v) represents a DCT coecient
disp('DCT Coefficients F(u, v):');
disp(dct_block);


% 亮度量化表
luminance_quant_table = [16 11 10 16 24 40 51 61; 12 12 14 19 26 58 60 55; 14 13 16 24 40 57 69 56; 14 17 22 29 51 87 80 62; 18 22 37 56 68 109 103 77; 24 35 55 64 81 104 113 92; 49 64 78 87 103 121 120 101; 72 92 95 98 112 100 103 99];

quantized_dct = round(dct_block ./ luminance_quant_table);

% ^ F(u; v) represents the quantized DCT coecients
disp('Quantized DCT Coefficients ^F(u; v):');
disp(quantized_dct);


% 反量化
dequantized_dct = quantized_dct .* luminance_quant_table;
disp('dequantized_dct ~F(u; v):');
disp(dequantized_dct);

% 逆DCT
reconstructed_block = idct2(dequantized_dct);
% 反中心化
reconstructed_block = reconstructed_block + 128;

disp('Reconstructed Image Block ~f(i; j):');
disp(reconstructed_block);

% Compute the error matrix
error_matrix = original_block - reconstructed_block;
% Display the error matrix
disp('Error Matrix:');
disp(error_matrix);































Ref:
https://slideplayer.com/slide/13812494/



留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header