Kompresja obrazów

Autorzy: Marek Domański

Pliki: rozdzial_18.zip

Przykład 18.1

W przykładzie (plik pred_I.m) przedstawiono w języku MATLAB działanie predykcji wewnątrzobrazowej, która przetwarza silnie skorelowany sygnał wejściowy w sygnał o bardzo nierównomiernym rozkładzie prawdopodobieństwa wartości próbek i charakteryzujący się w przybliżeniu zerową wartością średnią. Wykorzystanie funkcji zademonstrowano w przykładzie 18.1.A.
function pred_I(img_in, row);
% pred_I(img_in, row);
%
% Działanie predykcji wewnątrzobrazowej;
% Funkcja wyznacza błąd predykcji na podstawie wartości poprzedniej próbki;
%
% img_in - obraz wejściowy (monochromatyczny);
% row - numer wiersza;
%
% Przykład 18.1.
% m-plik (funkcyjny): pred_I.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autorzy rozdziału: Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecień 2014 r./MD.

dim = size(img_in);
if (row < 1 || row > dim(1)),
    fprintf('Wybrano numer wiersza spoza dozwolonego zakresu \n');
end;
img_out = img_in;
img_out(row,:)= 0;
A = double(img_in(row,:));  % próbki z wybranego wiersza

% Predykcja wartości bieżącej próbki na podstawie poprzedniej.
B = [128, A];
C = A-B(1:length(A));

    figure(1);
        imagesc(img_out, [0 255]); colormap(gray); axis off; axis image;
            title('Obraz oryginalny z zaznaczonym wybranym wierszem');
    figure(2);
        hist(A(1,:),256);
            title('Histogram wartości próbek w wybranym wierszu');
    figure(3);
        hist(C(1,:),513);
            title('Histogram bledu predykcji próbek w wybranym wierszu');

% KONIEC PRZYKŁADU 18.1.

Przykład 18.1.A

Demonstracja wykorzystania funkcji “pred_I” z przykładu 18.1. Plik przyklad_18_1_A.m.
% PRZYKŁAD 18.1.A
% plik: przyklad_18_1_A.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autor rozdziału:  Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecien 2014 r.

clc; clear; close all;

P=imread('lena.tif');

pred_I(P, 134);

% KONIEC PRZYKŁADU 18.1.

Przykład 18.2

Przykład (plik dct_proc.m) pokazuje w języku MATLAB, że nawet pominięcie większości próbek (wspołczynnikow) transformaty pozwala na odtworzenie obrazu zaskakująco podobnego do oryginału.
function dct_proc(img_in, proc),
% dct_proc(img_in, proc),
%
% Funkcja oblicza transformatę DCT dla całego obrazu, a następnie odtwarza obraz z zadanej liczby współczynników transformaty.
% img_in - obraz wejściowy (monochromatyczny);
% proc - procent współczynników transformaty (0-100%) użytych do odtworzenia obrazu;
%
% Przykład 18.2.
% m-plik (funkcyjny): dct_proc.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autorzy rozdziału: Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecień 2014 r./MD.

clc;

if (proc < 0 || proc > 100),
    fprintf('Wartość spoza zakresu 0 - 100 %% \n');
end;

dim = size(img_in);
img_dct=dct2D(img_in);
out_dct=zeros(dim(1),dim(2));
x=ceil(sqrt(dim(1)*dim(2)*(proc/100)));
out_dct(1:x,1:x)=img_dct(1:x,1:x);
out_img=idct2D(out_dct);

% przedstawienie wyników:
    figure(1);
        subplot(2,3,1); 
            imagesc(img_in, [0 255]);        colormap(gray);        axis image;
                title('Obraz oryginalny');
        subplot(2,3,2); 
            imagesc(abs(img_dct), [0 255]); axis image;
                title('Widmo obrazu oryginalnego');
        subplot(2,3,3); 
            imagesc(uint8(abs(double(img_in)-out_img)), [0 255]);   axis image;
                title('Róznica obrazów: oryginal-rekonstrukcja');
        subplot(2,3,4); 
            imagesc(out_img, [0 255]);                              axis image;
                title('Obraz zrekonstruowany');
        subplot(2,3,5); 
            imagesc(abs(out_dct), [0 255]);                         axis image;
                title('Widmo obrazu zrekonstruowanego');
        subplot(2,3,6); 
            imagesc(uint8(abs(double(img_in)-out_img)));            axis image;
                title('Przeskalowana róznica obrazów');

%--------------------------------------
% Funkcje lokalne
%--------------------------------------

function b=dct2D(arg1),
% b=dct2D(arg1),
%
% DCT2 2-D. Wyznacza dwuwymiarową transformatę kosinusową macierzy A.
% B = DCT2D(A)

[m, n] = size(arg1);
if (m > 1) && (n > 1),
    b = dct(dct(arg1).').';
else
    error('Rozmiar macierzy co najmniej 2x2');
end;
%--------------------------------------

function a = idct2D(arg1),
% a = idct2D(arg1),
%
% IDCT2 2-D . Wyznacza odwrotną dwuwymiarową transformatę kosinusową macierzy A.
% B = IDCT2D(A)

[m, n] = size(arg1);
if (m > 1) && (n > 1),
    a = idct(idct(arg1).').';
else
    error('Rozmiar macierzy co najmniej 2x2');
end;

% KONIEC PRZYKŁADU 18.2.

Przykład 18.2.A

Demonstracja wykorzystania funkcji “dct_proc” z przykładu 18.2. Plik przyklad_18_2_A.m.
% PRZYKŁAD 18.2.A
% plik: przyklad_18_2_A.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autor rozdziału:  Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecien 2014 r.

clc; clear; close all;

P=imread('lena.tif');

dct_proc(P, 50);

% KONIEC PRZYKŁADU 18.1.

Przykład 18.3

W przykładzie przedstawiono w języku MATLAB (plik motionEstES.m) estymację ruchu wykonywaną metodą pasowania bloków. Demonstracja wykorzystania funkcji znajduje się w - kolejnym - przykładzie 18.4.
function [motionVect] = motionEstES(imgP, imgI, mbSize, p),
% [motionVect] = motionEstES(imgP, imgI, mbSize, p),
% 
% Wyznaczenie wektorów ruchu metodą pełnego przeszukiwania;
% imgP - obraz dla którego szukamy wektorów ruchu;
% imgI - obraz odniesienia;
% mbSize - rozmiar bloku;
% p - zakres poszukiwania;
% motionVect - wektory ruchu dla kolejnych bloków w kolejności od lewej do prawej i z góry na dół;
%
% Przykład 18.3.
% m-plik (funkcyjny): motionEstES.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autor rozdziału: Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecień 2014 r./MD.

[row col] = size(imgI);
vectors = zeros(2,row*col/mbSize^2);
mbCount = 1;
for i = 1 : mbSize : row-mbSize+1,
    for j = 1 : mbSize : col-mbSize+1,
        cost=10^20;
        pos=[0 0];
        for m = -p : p,
            for n = -p : p,
                refBlkVer = i + m; % wiersz/współrzędna pioniowa;
                refBlkHor = j + n; % kolumna/współrzędna pozioma;
                if ( refBlkVer < 1 || refBlkVer+mbSize-1 > row || refBlkHor <1 || refBlkHor+mbSize-1 > col),
                    continue;
                end;
                % wyznaczenie kosztu:
                temp_cost = costFuncSAD(imgP(i:i+mbSize-1,j:j+mbSize-1),imgI(refBlkVer:refBlkVer+mbSize-1, refBlkHor:refBlkHor+mbSize-1));
                if (temp_cost <cost),
                    cost=temp_cost;
                    pos=[m n];
                end;
            end;
        end;
        vectors(1,mbCount) = pos(1); % wiersz/współrzędna pioniowa
        vectors(2,mbCount) = pos(2); % kolumna/współrzędna pozioma
        mbCount = mbCount + 1;
    end;
end;
motionVect = vectors;

% KONIEC PRZYKŁADU 18.3.

Przykład 18.4

W przykładzie przedstawiono w języku MATLAB (Plik przyklad_18_4.m) predykcję z kompensacją ruchu. Jest to jednocześnie demonstracja wykorzystania funkcji “motionEstES” z – poprzedniego - przykładu 18.3.
% PRZYKŁAD 18.4
% plik: przyklad_18_4.m
%
% Cyfrowe przetwarzanie sygnałów. Podstawy, multimedia, transmisja. PWN, Warszawa, 2014.
% Rozdział 18. Kompresja obrazów. 
% Autor rozdziału:  Marek Domański.
%
% Więcej na stronie internetowej: http://teledsp.kt.agh.edu.pl
%
% Opracowanie przykładu: kwiecien 2014 r./MD.

clc; clear; close all;

% wczytujemy obraz odniesienia:
ref_img=double(imread('lena.tif'));

% wprowadzenie "ruchu":
cur_img=ref_img(end:-1:1,end:-1:1);      % w tym przypadku dość radykalnie ...

% estymacja ruchu:
d=8;                                     % długość boku kwadratowego bloku obrazu;
A=motionEstES(cur_img, ref_img, d, 4*d); % uwaga: to może potrwać kilka minut...

% wyznaczenie obrazu predykcji na podstawie obrazu odniesienia i wyznaczonych wektorów ruchu:
img_out=motionComp(ref_img,A,d);

% wyświetlanie wyników:
    figure(1);
        subplot(2,3,1); 
            imagesc(ref_img,[0 255]);colormap(gray); axis image;
                title('Obraz odniesienia');
        subplot(2,3,2); 
            imagesc(cur_img,[0 255]);                axis image;
                title('Obraz kodowany');
        subplot(2,3,3); 
            imagesc(img_out,[0 255]);                axis image;
                title('Obraz przewidywany');
        subplot(2,3,4); 
            imagesc(abs(cur_img-ref_img),[0 255]);   axis image;
                title('Róznica obrazów kodowanego i odniesienia');  
        subplot(2,3,6); 
            imagesc(abs(cur_img-img_out),[0 255]);   axis image;
                title('Blad predykcji');
                
% składowe wektorów ruchu:
    figure(2);
        subplot(1,2,1); 
            hist(A(1,:),d*2+1);
                title('Histogram wektorów ruchu skladowej pionowej (y)');
        subplot(1,2,2); 
            hist(A(2,:),d*2+1);
                title('Histogram wektorów ruchu skladowej poziomej (x)');

% histogramy:
    figure(3);
        subplot(2,2,1); 
            hist(ref_img(:),256);
                title('Obraz odniesienia');
        subplot(2,2,2); 
            hist(cur_img(:),256);
                title('Obraz kodowany');
        subplot(2,2,3); 
            hist(cur_img(:)-ref_img(:),512);
                title('Róznica obrazów kodowanego i odniesienia');
        subplot(2,2,4); 
            hist(cur_img(:)-img_out(:),512);
                title('Blad predykcji');

% KONIEC PRZYKŁADU 18.4.