MATLAB tutorial (signals & images)

33 downloads 11108 Views 2MB Size Report
solving. Mathematical functions for linear algebra, statistics, Fourier analysis ... Functions for integrating MATLAB based algorithms with external .... Dare in input !
MATLAB - SCILAB High-level language for technical computing Development environment for managing code, files, and data Interactive tools for iterative exploration, design, and problem solving Mathematical functions for linear algebra, statistics, Fourier analysis, filtering, optimization, and numerical integration 2-D and 3-D graphics functions for visualizing data Tools for building custom graphical user interfaces Functions for integrating MATLAB based algorithms with external applications and languages, such as C, C++, Fortran, Java™...

Matrici - indicizzazione A = [1,2,3; 4,5,6; 7,8,9]

Matrice 3x3

V = [1 2 3 4]

Matrice 1 x 4 (vettore riga)

V = [1; 2; 3; 4]

Matrice 4 x 1 ( // colonna)

a = A(1,3)

Accesso casuale (lettura)

A(1,2) = 0

Assegnamento (scrittura)

A(3,4)

ERR! ! Indice eccede dim

B = A([1 2],[1 3])

Sottomatrice 2x2

C = A(1:3,2:end)

Sottomatrice 3x2

A(:,1) = 0

Assegnamento multiplo

A(1,:) = [10 20 30]

//

//

A(:,2) = []

Cancella seconda colonna

A(~isprime(A)) = 0

Indicizz. espress. logiche

n = find(A>=0)

Indici elem. che soddisfano …

[n m] = size(A)

Dim. della matrice

Matrici - operatori C = A*B

Prodotto canonico

C = A.*B

Prodotto elementwise

C = B*A

Non commuta...

C = B.*A

Commuta!

C = A==B

Test identità

A'

Trasposta

A^2

% A quadrata

Potenza

C^2

% C rettangolare

ERR! Uso operatore potenza

C.^4

Potenza elementwise

C = 2*A+B

Somma di matrici (espressione)

x = [1 2 3]; y = [4 5 6] a = x*y'

Prodotto interno

Matrici - operazioni A = zeros(n,m)

Matrice zeri

B = ones(size(A))

Matrice uni

I = eye(5)

Matrice identità

V = diag(A)

Diagonale della matrice

A = diag(V)

Matrice diagonale

A = rand(n,m)

Matrice casuale in [0,1]

A = randn(n,m)

Matrice di valori gaussiani

A = [B C]

Concatenazione

V = sum(A)

Somma per colonna

V = sum(A,2)

Somma per righe

a = sum(sum(A(1:3,2:3)))

Somma totale sottomatrice

B = inv(A)

Matrice inversa

a = det(A)

Determinante

B = log(A)

Logaritmo (elementwise)

Test 1 - Matrici Media: M𝑋 =

Covarianza:

1 𝑛

𝐶𝑋𝑌

𝑛

Varianza: 𝑆𝑋 =

𝑥𝑖 𝑖=1

1 = 𝑛

Dati i vettori casuali:

1 𝑛−1

𝑛

(𝑥𝑖 −𝑀)2

dove: 𝒙 ∈ ℝ𝑛

𝑖=1

𝑛

𝑥𝑖 − 𝑀𝑋 (𝑦𝑖 − 𝑀𝑌 )

Correlazione:

𝑅𝑋𝑌 =

𝑖=1

𝐶𝑋𝑌 𝑆𝑋 𝑆𝑌

𝒓 = (𝑟1 , …, 𝑟𝑛 ), 𝒑 = (𝑝1 , …,𝑝𝑛 ), 𝒒 = .3𝒓 + .7𝒑 + 4

Calcolare media, varianza, matrice di covarianza e di correlazione e confrontarli con quelli delle primitive di Matlab

M = mean(X)

Uso del comando sum

S = var(X) C = cov(X) R = corr(X)

Uso del prodotto

M = sum(X) X’*X

Soluzione Test 1 function demo_stat(N)

% Demo su media, varianza, covarianza e correlazione % - N = dimesione del campione

Y = X-repmat(MX,N,1); disp(['MY = ' num2str(mean(Y))]); % Varianza

% dati

r = randn(N,1); p = randn(N,1); q = .3*r+.7*p+4; X = [r p q];

% Media zero

% array Nx1 % array Nx1

% forma matriciale

S = var(X); disp(['S = ' num2str(S)]); % Covarianza

C = Y'*Y/(N-1); C1 = cov(X);

% Media

Mr = sum(r)/N; Mp = sum(p)/N; Mq = sum(q)/N;

disp('C = '); disp(C); disp('C1 = '); disp(C1);

disp('Mr Mp Mq =') disp([Mr Mp Mq])

% Correlazione

MX = mean(X); disp(['MX = ' num2str(MX)]);

disp('R = '); disp(R);

R = corr(X);

Segnali analogici t = -pi:0.01:pi

Insieme di tempi (campion.)

x = sin(t)

Funzione seno

y = t – t.^3/6 + t.^5/120

Sviluppo di MacLaurin (n=5)

plot(t,x)

Plot sin(t)

hold on

Plotting sovrapposti

plot(t,y,'r')

Plot approssimazione y(t) di colore rosso

Campionamento t = -pi:0.001:pi n = -pi:0.2:pi x = sin(t) y = sin(n) plot(t,x) hold on

Intervallo di tempo (~ cont) Campionamento f = 5 Hz, T = 0.2 sec Funzione continua Valori campionati Plot sin(t) (continuo)

plot(t,y,'r')

Plot sin(nT) (campioni)

Segnali discreti n = n1:n2

Intervallo

x = (n-n0)==0

Delta (di Kronecker) 𝑑(𝑛 − 𝑛0 )

x = (n >= n0)

Gradino unitario

u(𝑛 − 𝑛0 )

x = a.^n

Esponenziale reale

𝑎𝑛

x = exp((s+wi)*n)

Exp complesso

x = A*cos(2*pi*w*n+r)

Sinusoidale

x = 3*cos(2*pi*0.1*n+p1/3)…

Esempio...

+ 2*sin(0.5*pi*n)

𝑒 (𝑠+𝑖𝜔)𝑛 3 cos(2𝜋𝜔𝑛 + 1)

Segnale bidimensionale - Immagini

A = imread(‘Parasole.tif ’);

Legge immagine

imfinfo('Parasole.jpeg')

Informazioni sull’immagine (struct)

imshow(A);

Display dell’immagine

colormap(gray);

Cambia mappa colori

A(10,10,:)

Accesso ai valori RGB

A(10,:,:) = 0;

Cambia i valori

B = rgb2gray(A);

Conversione RGB -> Gray

T = im2bw(I, 0.1);

Tresholding dell’immagine

subplot(1,2,1), imshow(I);

Subplot originale

subplot(1,2,2), imshow(T);

Subplot sogliata

Test 2 - Immagini Tresholding di immagini in scala di grigi: for i = 1:size(I,1) for j = 1:size(I,2)

for each pixel I(i,j) within the image I if I(i,j) > threshold

if I(i,j) > thr

I(i,j) = 1

I(i,j) = 1 else

else

I(i,j) = 0

I(i,j) = 0 Dare in input!!

end

end end

end

end

Scrivere una function Matlab che, preso in input un’immagine e un numero (livelli di grigio), restituisca un’immagine con detto numero di livelli di grigio 4 livelli:

0

0

32

1 64

96

2 128

160

3 192

224

256

Originale

4 livelli grigio

black & white (tr = 0.5)

2 livelli grigio

8 livelli grigio

16 livelli grigio

Soluzione test2 function G = img2graylev(I,lev) % Clustering di immagini a livelli di grigio % - I = immagine (matrice) % - lev = numero di livelli di grigio % - G = immagine clusterizzata % immagine ricostruita G = uint8(zeros(size(I))); I = double(I);

% livelli di grigio L = ceil(256/lev); gr = round(L*[0:lev-1]+L/2); % clustering for i = 1:size(I,1) for j = 1:size(I,2) G(i,j) = gr(floor(I(i,j)/L)+1); end end

Conversione di tipo

Test 3 - istogramma L’istogramma di un’immagine mostra la frequenza relativa dei valori di intensità luminosa dell’insieme dei suoi pixel. La presenza di un picco in un istogramma rappresenta a seconda della posizione: una zona chiara o scura; una zona molto o poco contrastata.

Scrivere una programma Matlab che, preso in input un’immagine, restituisca il vettore delle frequenze e produca il grafico dell’istogramma

Soluzione test3 function freq = istogramma(I) % Visualizza l'istogramma dell'immagine % - I = immagine (in formato matriciale) % - freq = vettore frequenze freq = zeros(1,256); J = I(:); for i = 1:numel(J) freq(J(i)+1) = freq(J(i)+1)+1; end

da matrice ad array

% plotting in formato bar figure(1) bar(freq,.5,'linewidth',.01)

usato come indice

% equalizza l’istogramma dell’immagine Ieq = histeq(I) % visualizza l’istogramma imhist(I)

Convoluzione discreta +∞

Convoluzione:

𝑦(𝑛) =

+∞

𝑥 𝑘 ℎ 𝑛−𝑘 = 𝑘=−∞

ℎ 𝑘 𝑥 𝑛−𝑘 𝑘=−∞

Calcolare la convoluzione tra i due segnali:

x 𝑛 = 𝑢 𝑛 − 𝑢(𝑛 − 10)

h 𝑛 = 0.9𝑛 𝑢(𝑛)

Convoluzione - script % Filtro: x(n) e risp. h(n) nx = 0:30; nh = 0:50; x = (nx >= 0) - (nx >= 10); h = 0.9.^nh; [y,ny] = convoluzione(x,nx,h,nh);

Invocazione di una function

%plotting subplot(3,1,1) stem(nx,x,'fill') subplot(3,1,2) stem(nh,h,'fill') subplot(3,1,3) stem(ny,y,'fill')

function [y,ny] = convoluzione(x,nx,h,nh) % valori y = conv(x,h); % tempi: ny = nx(1) + nh(1):nx(end)+nh(end);

Test 3 - convoluzione Calcolare l’uscita del sistema con risposta all’impulso:

5

(−1)𝑘−1 𝑘 𝑑 𝑛 − 𝑘

ℎ(𝑛) =

𝑘=1

𝑥1 𝑛 = 𝑢 𝑛 − 1 − 𝑢(𝑛 − 15) E i segnali in ingresso:

𝑥2 𝑛 = cos

𝑛𝜋 , 𝑢 𝑛 − 1 − 𝑢(𝑛 − 15)12

Trasformata di Fourier discreta - DFT Se 𝑥 𝑛 è un segnale periodico di periodo Per = N𝑇, trasformata e antitrasformata di Fourier sono date da: 𝑁−1

𝑋 𝑘𝐹 = 𝑇

𝑛𝑘 −𝑗2π 𝑁 𝑥(𝑛𝑇)𝑒

𝑓 ∈ *0, 𝐹, 2𝐹, … , 𝑁 − 1 𝐹+

,

𝑛=0 𝑁−1

𝑥 𝑛𝑇 = 𝐹

𝑛𝑘 𝑗2π 𝑁 𝑋(𝑘𝐹)𝑒

1 𝐹= 𝑁𝑇

𝑥 = ,𝑥 0 , 𝑥 𝑇 , 𝑥 2𝑇 , … , 𝑥 𝑁 − 1 𝑇 -

,

𝑘=0

Ponendo 𝑇 = 1 , le procedure Matlab X = fft(x,N); calcolano rispettivamente: 𝑁−1

𝑋 𝑘+1 =

𝑥(𝑛 + 𝑛=0

Se 𝑇 ≠ 1 , basta porre :

𝑛𝑘 −𝑗2π 𝑁 1)𝑒

,

e

1 𝑥 𝑛+1 = 𝑁

𝑋 𝑘 + 1 = 𝑋(𝑘𝐹)/𝑇

x = ifft(X,N);

𝑁−1

𝑋(𝑘 + 𝑘=0

𝑛𝑘 𝑗2π 𝑁 1)𝑒

,

Calcolo esplicito DFT e FFT % calcolo DFT di x(n) X = zeros(1,N); for k = 1:N for n = 1:N X(k) = X(k) + x(n)*exp(-j*2*pi*(k-1)*(n-1)/N); end end % spettro modulo = abs(X) ; fase = angle(X); % trasformata tramite FFT X1 = fft(x,N);

% insieme delle frequenze nu = (0:1/N:(N-1)/N); stem(nu,modulo,'r');

DTFT vs DFT Esponenziale monolatera:

𝑥 𝑛 = 𝑎𝑛 𝑢(𝑛)



1 𝑋(𝜈) = 1 − 𝑎𝑒 −𝑗 2𝜋𝜈

DTFT : funzione periodica

DFT = campionamento DTFT sul periodo [0,1)

DFT di esponenziali - script %% Esempio di applicazione FFT % segnale esponenziale monolatero a = 0.5; n = 0:1:100; x = (a.^n) .* (n >= 0); stem(n,x); % Plotting trasformata teorica nu = -2:1/200:2; X = 1 ./ (1-a*exp(-2j*pi*nu)); modulo = abs(X); fase = angle(X); subplot(211); plot(nu,modulo); xlabel('nu'); ylabel('Modulo'); subplot(212); plot(nu,fase); xlabel('nu'); ylabel('Fase (rad)');

% trasformata tramite FFT nu = 0:1/100:1; % intervallo [0,1] X = 1 ./ (1-a*exp(-2j*pi*nu)); modulo = abs(X) ; fase = angle(X); N = 16; % numero campioni trasf. nu_fft = (0:1/N:(N-1)/N); X_fft = fft(x,N); figure(2) subplot(211); plot(nu, abs(X)); hold on; stem(nu_fft, abs(X_fft)); hold off subplot(212); plot(nu, angle(X)); hold on; stem(nu_fft, angle(X_fft)); hold off

DFT di 𝒓𝒆𝒄𝒕(𝒏) Esponenziale monolatera:

𝑥 𝑛 = 𝑟𝑒𝑐𝑡(𝑛)



sin 𝜋𝐿𝜈 𝑋(𝜈) = sin 𝜋𝜈 Inviluppo: funzione si𝑛𝑐 𝜈

Segnale 𝑟𝑒𝑐𝑡(𝑛)

DFT di 𝒓𝒆𝒄𝒕(𝒏) - script function DFT_rect(L,N) % Calcola N punti della DFT % di rect(n) % segnale rect = ones(1,L); % plotting modulo figure(1) stem(0:L-1,rect,'b','fill'); title('Segnale rect(n)'); % plotting DTFT f = 0:0.001:1; %frequenze X = sin(pi*f*L)./sin(pi*f); X = fftshift(X); modX = abs(X);

% calcolo FFT Y = fft(rect,N); Y = fftshift(Y); modY = abs(Y); % plotting modulo nu = 0:1/N:(N-1)/N; figure(2) stem(nu,modY,'b','fill'); hold on plot(f,modX,'r'); title('Modulo di X(\nu) e X(k)'); legend('DFT','DTFT') hold off

Elaborazioni d’immagini Filtri passa-basso

Eliminazione dei disturbi:

Media, gauss, mediana, motion blur, smoothing

Filtri passa-alto

Esaltazione dei particolari:

Sharpening, luminosità, contrasto, equalizzazione



Estrazione di informazioni:

Estrazione dei contorni (Gradiente, Laplaciano, Prewitt, Sobel) Segmentazione (region growing)

Filtraggio d’immagini Modifica di un pixel sulla base di una funzione del vicinato:

Filtraggio lineare: kernel o mask di convoluzione (combinazione lineare del vicinato)

Convoluzione:

𝐼𝑘𝑒𝑟 (𝑛, 𝑚) =

𝐾𝑒𝑟 𝑖, 𝑗 𝐼(𝑛 − 𝑖, 𝑚 − 𝑗) 𝑖=1𝑗=1

Convoluzione Kernel 3x3 - script K = 1/9*ones(3);

% filtro media 3x3

function I = conv_K_3x3(K,I) % Convoluzione di un'immagine con kernel 3x3 % INPUT: % - I = immagine % - K = kernel 3x3 % OUTPUT: % - I = immagine filtrata [n m] = size(I); J = double(I); % conversione per operaz. aritmetiche for i = 2:n-1 for j = 2:m-1 I(i,j) = sum(sum(K.*J(i-1:i+1,j-1:j+1))); end end

Filtri notevoli % Filtri notevoli A = imread('peppers.png'); % motion Kmo=fspecial('motion', 50, 54); Bmo=imfilter(A,Kmo,‘replicate'); % disk Kdi=fspecial('disk',10); Bdi=imfilter(A,Kdi,‘replicate'); % sobel Kso=fspecial('sobel'); Bso=imfilter(A,Kus,'replicate');

SINTASSI K = fspecial(type,parameters) Crea un kernel bidimensionale di un tipo specificato e relativi Parametri B = imfilter(A,K,option1,option2,...) Filtra un’immagine multidimensionale con il kernel specificato, secondo i rispettivi parametri

Modelli di rumore

% Aggiunta di rumore I = imread('cameraman.tif'); % rumore sale e pepe Isp = imnoise(I,'salt & pepper',0.03); % rumore gaussiano Ig = imnoise(I,'gaussian',0.02);

Filtri medio e mediano Filtro basato sulla media

Filtro basato sulla mediana

Scrivere una programma Matlab che realizzi il filtro mediano

Filtro mediano - script function I = median_filter(I,N) % Filtro mediano di un'immagine con kernel NxN % - I = immagine % - N = dimensione del kernel

M = floor(N/2); [n m] = size(I);

% offset = (size_kernel)/2

% padding iniziale

J = [I(:,1:M) I I(:,m-M)]; J = [J(1:M,:); J; J(n-M+1:n,:)]; % filtro

[n m] = size(J); for i = 1+M:n-M for j = 1+M:m-M K = J(i-M:i+M,j-M:j+M); s = sort(K(:)); I(i-M,j-M) = s(round(N^2/2)); end end I = uint8(I);

kernel

Applicazione dei filtri Filtro mediano

Filtro medio

Filtro gaussiano 2

Densità di probabilità gaussiana bidimensionale (continua):

−(𝑥 +𝑦 1 𝑓(𝑥, 𝑦) = 𝑒 2𝜎2 2 2𝜋𝜎

Progetto del kernel: 1. Costruire una griglia NxN di valori simmetrici attorno allo zero (usare meshgrid) [X,Y] = meshgrid(-2:.2:2, -2:.2:2); Z = exp(X.^2 + Y.^2);

2. Applicare la funzione di Gauss ai valori della griglia con sigma specificata 3. Normalizzare al fine di ottenere una densità di probabilità discreta Applicazione filtro gaussiano con 𝜎 = 2

2)

Kernel gaussiano - script function K = gauss_kernel(N,std) % Filtro Gaussiano % - N = Dimensione (NxN) del filtro % - std = deviazione standard % - K = kernel gaussiano dim

= (N-1)/2;

% preparazione griglia [x,y] = meshgrid(-dim:dim,-dim:dim); arg = -(x.*x + y.*y)/(2*std^2); % funzione di Gauss K = exp(arg); % normalizzazione s = sum(K(:)); if s ~= 0, K = K/s; end

DFT 2-D Se 𝑥 = 0,1,2, … , 𝑀 − 1, y = 0,1,2, … , 𝑁 − 1 e 𝐼(𝑥, 𝑦) un array 𝑀 × 𝑁 la sua DFT 2-D è:

1 𝐹(𝑢, 𝑣) = 𝑀𝑁

𝑀−1 𝑁−1

𝐼(𝑥, 𝑦) 𝑒

−2𝜋𝑗

𝑢𝑥 𝑣𝑦 + 𝑀 𝑁

𝑥=0 𝑦=0

𝑢 = 0,1,2, … , 𝑀 − 1

𝑣 = 0,1,2, … , 𝑁 − 1

L’antitrasformata è: 𝑀−1 𝑁−1

𝐼(𝑥, 𝑦) =

𝑢𝑥 𝑣𝑦 2𝜋𝑗 𝑀 + 𝑁 𝐹(𝑢, 𝑣) 𝑒

𝑢=0 𝑣=0

Le procedure Matlab sono:

F = fft2(I);

e I = ifft2(F);

FFT 2-D di un’immagine A=imread('cameraman.tif') % DFT dell’immagine FT=fft2(A); FT_c = fftshift(FT); subplot(2,3,1), imshow(A); subplot(2,3,2), imshow(log(1+abs(FT))); subplot(2,3,3), imshow(log(1+abs(FT_c))); % iDFT di FT Im1 = abs(ifft2(FT)); subplot(2,3,5), imshow(Im1,[]); % iDFT di FT_c Im2 = abs(ifft2(FT_c)); subplot(2,3,6), imshow(Im1,[]);

Filtraggio di un’immagine [xd,yd] = size(A); X = -xd./2:xd./2-1; Y = -yd./2:yd./2-1; [X,Y] = meshgrid(x,y); % filtro nel dom. frequenze sigma=32; arg=(X.^2+Y.^2)./sigma.^2; frqfilt=exp(-arg); % spettro non centrato imfilt1 = abs(ifft2(frqfilt.*FT));

% spettro centrato Imfilt2 = abs(ifft2(frqfilt.*FT_c)); % plotting subplot(1,3,1), imshow(frqfilt,[]); subplot(1,3,2), imshow(imfilt1,[]); subplot(1,3,3), imshow(imfilt2,[]);

Compressione alla Huffman • La tecnica più nota per la riduzione della ridondanza di codifica è dovuta a D.A. Huffman: essa realizza la migliore performance possibile in caso di codifica individuale dei simboli emessi da una sorgente • I codici Huffman sono pertanto codici a codeword di lunghezza variabile: i simboli dell’alfabeto che costituiscono il messaggio sono codificati con sequenze di bit di diversa lunghezza • La potenza dei codici Huffman sta nel fatto che tutte le parole del codice sono univocamente decodificabili • Si considerino per esempio i simboli di seguito, con i rispettivi codici: A B C D

0 10 110 111

• La sequenza di bit 01101110100 è decodificabile univocamente come `ACDABA`

Codice di Huffman % Es. Uso di huffmandict(symbols,p) symbols = [1:5]; p = [.3 .3 .2 .1 .1]; [dict,avglen] = huffmandict(symbols,p) dict = [1] [2] [3] [4] [5]

[1x2 [1x2 [1x2 [1x3 [1x3

avglen =

double] double] double] double] double]

1

. . . end %-------------------------% Sub Function function p = dist_prob(I) . . . end

2.2000

samplecode = dict{5,2}

1

% file Huff_encode.m function [code code_w]= Huff_encode(I)

0

% file Huff_decode.m function I=Huff_decode(code,code_w,N,M) . . .

Costruire una procedura per la compressione e decompressione con la codifica di Huffman

Huffman encode function [code dict] = Huff_encode(I) % Codifica di Huffman code_len = 0; code = []; symb = 0:255; p = dist_prob(I); [dict avglen] = huffmandict(symb,p); J = I(:); for i = 1:numel(J) c = dict{J(i),2}; code_len = code_len+numel(c); code = [code c]; End fprintf('Lungh media parola codice = %f\n',avglen); fprintf('Lungh codice = %d\n',code_len); fprintf('compression ratio = %.2f\n',numel(J)*8/code_len); end