matlab - scilab - ens.di.unimi.itens.di.unimi.it/tutorial/matlab_tutorial_signals_images.pdf ·...
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
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