基于8×8 DCT变换的图像压缩MATLAB实现

将图像分割为8×8块,进行DCT变换、量化和压缩,最后重建图像并评估压缩效果。

function dctImageCompression(imagePath, quality)
    % 读取图像
    if nargin < 1
        imagePath = 'cameraman.tif'; % 默认图像
    end
    if nargin < 2
        quality = 50; % 默认压缩质量(0-100)
    end
    
    % 读取图像并转换为双精度
    originalImage = imread(imagePath);
    if size(originalImage, 3) == 3
        originalImage = rgb2gray(originalImage);
    end
    originalImage = im2double(originalImage);
    
    % 显示原始图像
    figure('Name', 'DCT图像压缩', 'Position', [100, 100, 1000, 500]);
    subplot(2, 3, 1);
    imshow(originalImage);
    title(sprintf('原始图像 (%dx%d)', size(originalImage,2), size(originalImage,1)));
    
    % 定义8×8量化矩阵 (基于JPEG标准)
    quantizationMatrix = [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];
    
    % 调整量化质量 (quality: 1-100)
    if quality <= 0
        quality = 1;
    elseif quality > 100
        quality = 100;
    end
    
    if quality < 50
        scalingFactor = 5000 / quality;
    else
        scalingFactor = 200 - 2 * quality;
    end
    
    quantizationMatrix = floor((quantizationMatrix * scalingFactor + 50) / 100);
    quantizationMatrix(quantizationMatrix < 1) = 1;
    
    % 填充图像使其尺寸为8的倍数
    [rows, cols] = size(originalImage);
    paddedRows = ceil(rows / 8) * 8;
    paddedCols = ceil(cols / 8) * 8;
    paddedImage = padarray(originalImage, [paddedRows-rows, paddedCols-cols], 'replicate', 'post');
    
    % 初始化变量
    dctCoeffs = zeros(size(paddedImage));
    quantizedCoeffs = zeros(size(paddedImage));
    reconstructedImage = zeros(size(paddedImage));
    
    % 压缩率统计
    totalCoeffs = numel(paddedImage);
    nonZeroCoeffs = 0;
    
    % 处理每个8×8块
    for i = 1:8:paddedRows
        for j = 1:8:paddedCols
            % 提取当前块
            block = paddedImage(i:i+7, j:j+7);
            
            % DCT变换
            dctBlock = dct2(block);
            dctCoeffs(i:i+7, j:j+7) = dctBlock;
            
            % 量化
            quantBlock = round(dctBlock ./ quantizationMatrix);
            quantizedCoeffs(i:i+7, j:j+7) = quantBlock;
            
            % 统计非零系数
            nonZeroCoeffs = nonZeroCoeffs + nnz(quantBlock);
            
            % 反量化
            dequantBlock = quantBlock .* quantizationMatrix;
            
            % IDCT重建
            reconstructedImage(i:i+7, j:j+7) = idct2(dequantBlock);
        end
    end
    
    % 裁剪回原始尺寸
    reconstructedImage = reconstructedImage(1:rows, 1:cols);
    
    % 计算压缩率和PSNR
    compressionRatio = totalCoeffs / nonZeroCoeffs;
    mse = mean((originalImage(:) - reconstructedImage(:)).^2);
    psnr = 10 * log10(1 / mse);
    
    % 显示结果
    subplot(2, 3, 2);
    imshow(paddedImage);
    title('填充后的图像');
    
    subplot(2, 3, 3);
    imshow(log(abs(dctCoeffs) + 1), []);
    colormap(jet); colorbar;
    title('DCT系数 (对数尺度)');
    
    subplot(2, 3, 4);
    imshow(abs(quantizedCoeffs), [0, max(quantizedCoeffs(:))]);
    colormap(jet); colorbar;
    title('量化后的系数');
    
    subplot(2, 3, 5);
    imshow(reconstructedImage);
    title(sprintf('重建图像 (质量: %d%%)', quality));
    
    subplot(2, 3, 6);
    diffImage = abs(originalImage - reconstructedImage) * 5; % 放大误差
    imshow(diffImage);
    title(sprintf('误差图 (x5放大)'));
    
    % 显示压缩信息
    fprintf('图像尺寸: %d x %d\n', cols, rows);
    fprintf('压缩质量: %d%%\n', quality);
    fprintf('压缩率: %.2f:1\n', compressionRatio);
    fprintf('非零系数比例: %.2f%%\n', (nonZeroCoeffs/totalCoeffs)*100);
    fprintf('PSNR: %.2f dB\n', psnr);
    fprintf('MSE: %.6f\n', mse);
    
    % 保存结果
    saveas(gcf, 'dct_compression_result.png');
end

示例

% 示例1:使用默认图像和默认质量(50%)
dctImageCompression();

% 示例2:指定图像和质量
dctImageCompression('peppers.png', 75);

% 示例3:高质量压缩
dctImageCompression('mandril.tif', 90);

% 示例4:低质量高压缩
dctImageCompression('satellite.jpg', 10);

算法说明

1. DCT变换核心原理

  • 将8×8图像块转换为频域表示
  • 公式:\(F(u,v) = \frac{1}{4}C(u)C(v)\sum_{x=0}^{7}\sum_{y=0}^{7}f(x,y)\cos\left(\frac{(2x+1)u\pi}{16}\right)\cos\left(\frac{(2y+1)v\pi}{16}\right)\)
  • 其中 \(C(u) = \begin{cases} 1/\sqrt{2} & \text{if } u=0 \\ 1 & \text{otherwise} \end{cases}\)

2. 量化过程

  • 使用JPEG标准量化矩阵作为基础
  • 根据质量因子调整量化步长:
    • 高质量 → 小步长 → 保留更多细节
    • 低质量 → 大步长 → 更高压缩率

3. 压缩机制

  • 高频分量通常具有较小值,量化后变为零
  • 使用行程编码(RLE)和霍夫曼编码可进一步压缩(本实现中省略)
  • 仅存储非零系数可显著减少数据量

4. 性能评估

  • 压缩率:原始数据量 / 压缩后数据量
  • PSNR:峰值信噪比,衡量重建质量
    \(PSNR = 10 \log_{10}\left(\frac{MAX^2}{MSE}\right)\)
  • MSE:均方误差
    \(MSE = \frac{1}{MN}\sum_{i=0}^{M-1}\sum_{j=0}^{N-1}[I(i,j)-K(i,j)]^2\)

参考代码 把图像分成8×8的图像块进行DCT变换压缩 www.youwenfan.com/contentcnl/83441.html

参数

  1. 量化矩阵:控制不同频率分量的压缩程度

  2. 质量因子:0-100之间的值,控制整体压缩质量

    • 90+:接近无损压缩
    • 70-80:良好视觉质量
    • 50:中等压缩
    • 30以下:明显压缩伪影
  3. 块尺寸:8×8是JPEG标准,平衡计算效率和压缩性能

此实现展示了DCT压缩的核心原理,实际应用中可结合熵编码和更先进的量化策略进一步提升压缩效率。

posted @ 2025-11-10 10:37  老夫写代码  阅读(28)  评论(0)    收藏  举报