我想问一下jpeg中的压缩。 我无法保存压缩图像,只能保存解压缩后的图像。 我也无法进行熵解码。 我希望有一个人可以帮助我。我使用的是MATLAB R2012a。我需要压缩图像文件来显示我已经压缩并且可以计算未压缩和压缩图像之间的比率。以下是代码:
function [ output_image, compressed_vector, ratio ] = jpeg_computing( input_image, q)
runtime = cputime;
n = 8; % size of blocks
dim1 = size(input_image,1); % image width
dim2 = size(input_image,2); % image height
dim3 = size(input_image,3); % number of channels
if (dim3 > 1)
ycbcrmap = rgb2ycbcr(im2double(input_image)); % mapping, need double for DCT
else
ycbcrmap = im2double(input_image);
end
% here you can (should) also paste downsampling of chroma components
output_image = zeros(size(input_image), 'double');
compressed_vector = 0;
[qY, qC] = get_quantization(q); % get quantization matrices
T = dctmtx(n); % DCT matrix
scale = 255; % need because DCT values of YCbCr are too small to be quantized
% Block processing functions
dct = @(block_struct) T * block_struct.data * T';
invdct = @(block_struct) T' * block_struct.data * T;
quantY = @(block_struct) round( block_struct.data./qY);
dequantY = @(block_struct) block_struct.data.*qY;
quantC = @(block_struct) round( block_struct.data./qC);
dequantC = @(block_struct) block_struct.data.*qC;
entropy_proc = @(block_struct) entropy_cod(block_struct.data, n);
%---------------------------
for ch=1:dim3
% encoding ---------------------------
channel = ycbcrmap(:,:,ch); % get channel
% compute scaled forward DCT
channel_dct = blockproc(channel, [n n], dct).*scale;
% quantization
if (ch == 1)
channel_q = blockproc(channel_dct,[n n], quantY); % quantization for luma
else
channel_q = blockproc(channel_dct,[n n], quantC); % quantization for colors
end
entropy_out = blockproc(channel_q,[n n], entropy_proc); % compute entropy code
entropy_code = get_entropy(entropy_out, n, dim1, dim2); % get entropy code without
zeros on the end
[comp, dict] = huffman_cod(entropy_code); % huffman encoding
compressed_vector = cat(1, compressed_vector, comp); % add to output
% decoding ---------------------------
dsig = reshape(huffmandeco(comp, dict), size(entropy_code)); % huffman decoding
if (isequal(entropy_code,dsig) ~= 1) % check if decoding is correct
input('error in huffmandeco')
end
% put entropy decoding here
% dequantization
if (ch == 1)
channel_q = blockproc(channel_q,[n n], dequantY);
else
channel_q = blockproc(channel_q,[n n], dequantC);
end
output_data = blockproc(channel_q./scale,[n n],invdct); % inverse DCT, scale back
output_image(:,:,ch) = output_data(1:dim1, 1:dim2); % set output
end
%---------------------------
compressed_vector = compressed_vector(2:length(compressed_vector)); % remove first
symbol
if (dim3 > 1)
output_image = im2uint8(ycbcr2rgb(output_image)); % back to rgb uint8
else
output_image = im2uint8(output_image); % back to rgb uint8
end
runtime = cputime-runtime;
% compute compression ratio
% compressed_vector is binary, input image has one byte per pixel
ratio = (dim1 * dim2 * dim3 / (length(compressed_vector) /8));
tampil = guidata(gcbo);
str1 = num2str(ratio,'%1.2f %%');
str2 = num2str(runtime,'%1.2f s');
set(tampil.edit2,'String',str1);
set(tampil.edit3,'String',str2);
axes(tampil.axes_asli), imshow(input_image) % show results
axes(tampil.axes_hasil), imshow(output_image) % show results
end
function [entropy_code] = get_entropy (entropy_raw_matrix, n, dim1, dim2)
% go by tiles in loops to extract shortened entropy codes (without
% zeros on the end)
step = n-1; % poor stuff for entropy coding iterations, should be avoided
tile = entropy_raw_matrix(1:1+step, 1:1+step);
entropy_code = tile(1:find(tile(:),1,'last'));
for i=step+2:step+1:dim1-step
for j=step+2:step+1:dim2-step
tile = entropy_raw_matrix(i:i+step, j:j+step);
entropy_code = cat(2, entropy_code, tile(1:find(tile(:),1,'last')));
end
end
end