% сжатие
clear;
img_rgb = imread('astrologer.bmp');
figure (1);
subplot(1,2,1);
imshow(img_rgb);
title('Исходное изображение');
set(1,'name','JPEG');
img_ybr = rgb2ycbcr(img_rgb);
Y = img_ybr(:,:,1);
Cb = img_ybr(:,:,2);
Cr = img_ybr(:,:,3);
width = length(img_ybr(1,:,:));
height = length(img_ybr(:,1,:))
blocksize = 8;
q = 6; %
степень сжатия
for i=1:1:blocksize
for j=1:1:blocksize
Q(i,j) = 1+(1+i+j)*q;
end;
end;
i = 1;
j = 1;
max_i = fix(height/8)*8;
max_j = fix(width/8)*8;
res_Y = zeros(max_i,max_j);
l_yi = 1;
l_cbi = 1;
l_cri = 1;
Yt = zeros(max_i,max_j);
%ДКП и квантование
while i < max_i
j = 1;
while j < max_j
br_part = dct2(Y(i:i+blocksize-1,j:j+blocksize-1));
br_part = round(br_part./Q);
blue_part = dct2(Cb(i:i+blocksize-1,j:j+blocksize-1));
blue_part = round(blue_part./Q);
red_part = dct2(Cr(i:i+blocksize-1,j:j+blocksize-1));
red_part = round(red_part./Q);
for ii=1:1:blocksize
for jj=1:1:blocksize
l_Y(l_yi) = br_part(ii, jj);
l_yi = l_yi+1;
l_Cb(l_cbi) = blue_part(ii, jj);
l_cbi = l_cbi+1;
l_Cr(l_cri) = red_part(ii, jj);
l_cri = l_cri+1;
end;
end;
j = blocksize+j;
end;
i = blocksize+i;
end;
yj = 1;
cbj = 1;
crj = 1;
y_zero_count = 0;
cb_zero_count = 0;
cr_zero_count = 0;
%сжатие
for i=1:1:length(l_Y)
if (l_Cb(i) ~= 0)
if (cb_zero_count ~= 0)
coded_Cb(cbj) = 0;
cbj = cbj+1;
coded_Cb(cbj) = cb_zero_count;
cb_zero_count = 0;
cbj = cbj+1;
end;
coded_Cb(cbj) = l_Cb(i);
cbj = cbj+1;
else
cb_zero_count = cb_zero_count+1;
end;
if (l_Y(i) ~= 0)
if (y_zero_count ~= 0)
coded_Y(yj) = 0;
yj = yj+1;
coded_Y(yj) = y_zero_count;
y_zero_count = 0;
yj = yj+1;
end;
coded_Y(yj) = l_Y(i);
yj = yj+1;
else
y_zero_count = y_zero_count+1;
end;
if (l_Cr(i) ~= 0)
if (cr_zero_count ~= 0)
coded_Cr(crj) = 0;
crj = crj+1;
coded_Cr(crj) = cr_zero_count;
cr_zero_count = 0;
crj = crj+1;
end;
coded_Cr(crj) = l_Cr(i);
crj = crj+1;
else
cr_zero_count = cr_zero_count+1;
end;
end;
if (cb_zero_count ~=0)
coded_Cb(cbj) = 0;
cbj = cbj+1;
coded_Cb(cbj) = cb_zero_count;
end;
if (y_zero_count ~=0)
coded_Y(yj) = 0;
yj = yj+1;
coded_Y(yj) = y_zero_count;
end;
if (cr_zero_count ~=0)
coded_Cr(crj) = 0;
crj = crj+1;
coded_Cr(crj) = cr_zero_count;
end;
% запись в файл сжатый массив и фактор качества, и размер изображения
f = fopen('coded.img','wb');
res = [coded_Y,coded_Cb,coded_Cr];
fprintf(f,'%d %d %d ',max_i,max_j,q);
for i=1:1:length(res);
fprintf(f,'%d ',res(i));
end;
fclose(f);
%
восстановление
clear;
blocksize = 8;
f = fopen('coded.img','rb');
sourse = fscanf(f,'%d');
fclose(f);
width = sourse(2);
height = sourse(1);
q = sourse(3);
N_sourse = length(sourse);
sourse = sourse(4:N_sourse);
N_sourse = N_sourse-3;
% декомпрессия изображения
j = 1;
i = 1;
while (i
if (sourse(i) ~= 0)
out(j) = sourse(i);
j = j+1;
i = i+1;
else
out(j:j+sourse(i+1)) = 0;
j = j+sourse(i+1);
i = i+2;
end;
end;
%
разбиение на яркость, синий, красный
new_length = fix(length(out)/8)*8;
out = out(1:new_length);
part_length = new_length/3;
%вычисление матрицы квантов
for i=1:1:blocksize
for j=1:1:blocksize
Q(i,j) = 1+(1+i+j)*q;
end;
end;
% формирование массивов
l_Y = out(1:part_length);
l_Cb = out(part_length+1:part_length+part_length);
l_Cr = out(part_length+part_length+1:part_length+part_length+part_length);
%
вычисление кол-ва матриц
N_elem = blocksize*blocksize;
N_matr = round(part_length/(N_elem));
i_block = 1;
i = 1;
while i < height
j = 1;
while j < width
yblock_64 = l_Y(i_block:i_block+N_elem-1);% выделяемм 64 элемента
cbblock_64 = l_Cb(i_block:i_block+N_elem-1);
crblock_64 = l_Cr(i_block:i_block+N_elem-1);
l_yi = 1;
for ii=1:1:blocksize
for jj=1:1:blocksize
br_part(ii, jj) = yblock_64(l_yi);%
записываем в матрицу
blue_part(ii, jj) = cbblock_64(l_yi);
red_part(ii, jj) = crblock_64(l_yi);
l_yi = l_yi+1;
end;
end;
%для записи другого блока (запись c 65)
i_block = i_block+64;
% деквантование
br_part = br_part.*Q;
blue_part = blue_part.*Q;
red_part = red_part.*Q;
% обратное
косинусное преобразование
Y(i:i+blocksize-1,j:j+blocksize-1) = idct2(br_part);
Cb(i:i+blocksize-1,j:j+blocksize-1) = idct2(blue_part);
Cr(i:i+blocksize-1,j:j+blocksize-1) = idct2(red_part);
j = j+blocksize;
end;
i = i+blocksize;
end;
% формирование изображения
img_ybr(:,:,1) = uint8(Y);
img_ybr(:,:,2) = uint8(Cb);
img_ybr(:,:,3) = uint8(Cr);
img_rgb = ycbcr2rgb(img_ybr);
%изображение
figure (1);
subplot(1,2,2);
imshow(img_rgb,'truesize');%вывод
изображения на экран
title('Сжатое изображение');