matlab - scilab - ens.di.unimi.itens.di.unimi.it/tutorial/matlab_tutorial_signals_images.pdf ·...

40
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™... MATLAB - SCILAB

Upload: dangquynh

Post on 06-Mar-2018

244 views

Category:

Documents


0 download

TRANSCRIPT

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™...

MATLAB - SCILAB

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

V = [1 2 3 4]

V = [1; 2; 3; 4]

a = A(1,3)

A(1,2) = 0

A(3,4)

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

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

A(:,1) = 0

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

A(:,2) = []

A(~isprime(A)) = 0

n = find(A>=0)

[n m] = size(A)

Matrice 3x3

Matrice 1 x 4 (vettore riga)

Matrice 4 x 1 ( // colonna)

Accesso casuale (lettura)

Assegnamento (scrittura)

ERR! ! Indice eccede dim

Sottomatrice 2x2

Sottomatrice 3x2

Assegnamento multiplo

// //

Cancella seconda colonna

Indicizz. espress. logiche

Indici elem. che soddisfano …

Dim. della matrice

Matrici - indicizzazione

C = A*B

C = A.*B

C = B*A

C = B.*A

C = A==B

A'

A^2 % A quadrata

C^2 % C rettangolare

C.^4

C = 2*A+B

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

a = x*y'

Prodotto canonico

Prodotto elementwise

Non commuta...

Commuta!

Test identità

Trasposta

Potenza

ERR! Uso operatore potenza

Potenza elementwise

Somma di matrici (espressione)

Prodotto interno

Matrici - operatori

A = zeros(n,m)

B = ones(size(A))

I = eye(5)

V = diag(A)

A = diag(V)

A = rand(n,m)

A = randn(n,m)

A = [B C]

V = sum(A)

V = sum(A,2)

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

B = inv(A)

a = det(A)

B = log(A)

Matrice zeri

Matrice uni

Matrice identità

Diagonale della matrice

Matrice diagonale

Matrice casuale in [0,1]

Matrice di valori gaussiani

Concatenazione

Somma per colonna

Somma per righe

Somma totale sottomatrice

Matrice inversa

Determinante

Logaritmo (elementwise)

Matrici - operazioni

Test 1 - Matrici

M𝑋 =1

𝑛 𝑥𝑖

𝑛

𝑖=1

Dati i vettori casuali: 𝒓 = (𝑟1, …, 𝑟𝑛), 𝒑 = (𝑝1, …,𝑝𝑛), 𝒒 = .3𝒓 + .7𝒑 + 4

Media: 𝑆𝑋 =1

𝑛 − 1 (𝑥𝑖−𝑀)

2

𝑛

𝑖=1

Varianza:

𝐶𝑋𝑌 =1

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

𝑛

𝑖=1

Covarianza: 𝑅𝑋𝑌 =𝐶𝑋𝑌

𝑆𝑋𝑆𝑌 Correlazione:

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

M = mean(X)

S = var(X)

C = cov(X)

R = corr(X)

dove: 𝒙 ∈ ℝ𝑛

Uso del comando sum

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 % dati r = randn(N,1); % array Nx1 p = randn(N,1); % array Nx1 q = .3*r+.7*p+4; X = [r p q]; % forma matriciale % Media Mr = sum(r)/N; Mp = sum(p)/N; Mq = sum(q)/N; disp('Mr Mp Mq =') disp([Mr Mp Mq]) MX = mean(X); disp(['MX = ' num2str(MX)]);

% Media zero Y = X-repmat(MX,N,1); disp(['MY = ' num2str(mean(Y))]); % Varianza S = var(X); disp(['S = ' num2str(S)]); % Covarianza C = Y'*Y/(N-1); C1 = cov(X); disp('C = '); disp(C); disp('C1 = '); disp(C1); % Correlazione R = corr(X); disp('R = '); disp(R);

t = -pi:0.01:pi

x = sin(t)

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

plot(t,x)

hold on

plot(t,y,'r')

Insieme di tempi (campion.)

Funzione seno

Sviluppo di MacLaurin (n=5)

Plot sin(t)

Plotting sovrapposti

Plot approssimazione y(t) di colore rosso

Segnali analogici

t = -pi:0.001:pi

n = -pi:0.2:pi

x = sin(t)

y = sin(n)

plot(t,x)

hold on

plot(t,y,'r')

Intervallo di tempo (~ cont)

Campionamento f = 5 Hz, T = 0.2 sec

Funzione continua

Valori campionati

Plot sin(t) (continuo)

Plot sin(nT) (campioni)

Campionamento

n = n1:n2

x = (n-n0)==0

x = (n >= n0)

x = a.^n

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

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

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

+ 2*sin(0.5*pi*n)

Intervallo

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

Gradino unitario u(𝑛 − 𝑛0)

Esponenziale reale 𝑎𝑛

Exp complesso 𝑒(𝑠+𝑖𝜔)𝑛

Sinusoidale 3 cos(2𝜋𝜔𝑛 + 1)

Esempio...

Segnali discreti

Segnale bidimensionale - Immagini

A = imread(‘Parasole.tif ’);

imfinfo('Parasole.jpeg')

imshow(A);

colormap(gray);

A(10,10,:)

A(10,:,:) = 0;

B = rgb2gray(A);

T = im2bw(I, 0.1);

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

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

Legge immagine

Informazioni sull’immagine (struct)

Display dell’immagine

Cambia mappa colori

Accesso ai valori RGB

Cambia i valori

Conversione RGB -> Gray

Tresholding dell’immagine

Subplot originale

Subplot sogliata

Test 2 - Immagini

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

if I(i,j) > threshold

I(i,j) = 1

else

I(i,j) = 0

end

end

for i = 1:size(I,1)

for j = 1:size(I,2)

if I(i,j) > thr

I(i,j) = 1

else

I(i,j) = 0

end

end

end

Tresholding di immagini in scala di grigi:

Dare in input!!

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

0 64 128 192 256

0 1 2 3 4 livelli:

32 96 160 224

Originale black & white (tr = 0.5) 2 livelli grigio

16 livelli grigio 8 livelli grigio 4 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 % plotting in formato bar figure(1) bar(freq,.5,'linewidth',.01)

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

da matrice ad array

usato come indice

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); %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);

Invocazione di una function

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

𝑥1 𝑛 = 𝑢 𝑛 − 1 − 𝑢(𝑛 − 15)

ℎ(𝑛) = (−1)𝑘−1𝑘 𝑑 𝑛 − 𝑘

5

𝑘=1

E i segnali in ingresso: 𝑥2 𝑛 = cos

𝑛𝜋

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

Trasformata di Fourier discreta - DFT

Se 𝑥 𝑛 è un segnale periodico di periodo Per = N𝑇, trasformata e antitrasformata di Fourier sono date da:

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

𝑁−1

𝑛=0

, 𝐹 =1

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

𝑥 𝑛𝑇 = 𝐹 𝑋(𝑘𝐹)𝑒𝑗2π𝑛𝑘𝑁

𝑁−1

𝑘=0

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

Ponendo 𝑇 = 1 , le procedure Matlab e calcolano rispettivamente:

𝑋 𝑘 + 1 = 𝑥(𝑛 + 1)𝑒−𝑗2π𝑛𝑘𝑁

𝑁−1

𝑛=0

, 𝑥 𝑛 + 1 =1

𝑁 𝑋(𝑘 + 1)𝑒𝑗2π

𝑛𝑘𝑁

𝑁−1

𝑘=0

,

X = fft(x,N); x = ifft(X,N);

Se 𝑇 ≠ 1 , basta porre : 𝑋 𝑘 + 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

Eliminazione dei disturbi:

Esaltazione dei particolari:

Estrazione di informazioni:

Filtri passa-basso

Media, gauss, mediana, motion blur, smoothing

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

Filtri passa-alto

Sharpening, luminosità, contrasto, equalizzazione

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)

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

𝑗 = 1𝑖 = 1

Convoluzione:

Convoluzione Kernel 3x3 - script

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

K = 1/9*ones(3); % filtro media 3x3

Filtri notevoli

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

% 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');

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); % offset = (size_kernel)/2 [n m] = size(I); % 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

Densità di probabilità gaussiana bidimensionale (continua): 𝑓(𝑥, 𝑦) =1

2𝜋𝜎2𝑒−(𝑥2+𝑦2)2𝜎2

Progetto del kernel:

1. Costruire una griglia NxN di valori simmetrici attorno allo zero (usare meshgrid)

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

[X,Y] = meshgrid(-2:.2:2, -2:.2:2); Z = exp(X.^2 + Y.^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

𝑦=0

𝑀−1

𝑥=0

𝑒−2𝜋𝑗

𝑢𝑥𝑀+𝑣𝑦𝑁

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

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

L’antitrasformata è:

𝐼(𝑥, 𝑦) = 𝐹(𝑢, 𝑣)

𝑁−1

𝑣=0

𝑀−1

𝑢=0

𝑒2𝜋𝑗𝑢𝑥𝑀+𝑣𝑦𝑁

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 0 B 10 C 110 D 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] [1x2 double] [2] [1x2 double] [3] [1x2 double] [4] [1x3 double] [5] [1x3 double] avglen = 2.2000 samplecode = dict{5,2} 1 1 0

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

% file Huff_encode.m function [code code_w]= Huff_encode(I) . . . end %-------------------------- % Sub Function function p = dist_prob(I) . . . end

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

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