Architettura di un sistema di PR
Ciclo di progettazione di un sistema di
PR
Estrazione delle feature
Una volta acquisito il dato da elaborare, tramite gli appositi
sensori, è necessario estrarre le misure in grado di
caratterizzarlo (features).
L'oggetto da classificare sarà quindi rappresentato da un
insieme (vettore) di features, denominato pattern.
Il problema principale della scelta delle features consiste nel
fatto che la mia rappresentazione numerica dell'oggetto da
classificare deve consentire di discriminare le diverse classi,
ovvero:
Oggetti appartenenti alla stessa classe devono essere
“simili” fra loro, ed il più possibile “diversi” da quelli delle
altre classi.
Estrazione delle features
La scelta delle features risulta quindi di primaria importanza
e dipende dalla tipologia del dato (fotografia, impronta, volto,
testo, ...) e dalle categorie in cui classificarlo, esempio:
 immagine di interni o di esterni;
 immagine di mare, montagna, o città;
 e-mail di spam o leggittima;
 documento di sport, economia, politica o tecnologia;
 riconoscimento o verifica dell'identità
In alcuni casi, nonostante sia abbastanza semplice
individuare le feature discriminanti, risulta particolarmente
complessa la loro estrazione (es. posizione di occhi, naso e
bocca in un volto).
Estrazione delle features
Consideriamo due problemi pratici di estrazione delle features da
immagini:

Catalogazione di immagini “Indoor” e “Outdoor”

Riconoscimento di immagini di spam
Estrazione delle features
Catalogazione di immagini “Indoor” e “Outdoor”
Che cosa è in grado di distinguere le due categorie?
 Indoor: meno luminose, possono avere pareti o comunque aree
uniformi
 Outdoor: possono contenere cielo, alberi e prati, hanno spesso più
dettagli (es foglie)
Possibili feature:
 distribuzione dei colori (istogramma della frequenza dei colori)
 texture (es Wavelet, DCT, ...)
Estrazione delle features
Riconoscimento di immagini di spam
Che cosa è in grado di distinguere le due categorie?
 Legittime: tipicamente sono fotografie, potrebbero essere banner
 Spam: tipicamente contengono testo su sfondo uniforme (o quasi
uniforme)
Possibili feature:
 Informazioni estratte dalla distribuzione dei colori come: numero dei
colori e occupazione del colore più comune
 aspect ratio dell'immagine
 area del testo
Calcolo distribuzione dei colori
La distribuzione dei colori di una immagine è tipicamente
data dall'istogramma dei colori, ovvero dalla stima del
numero di occorrenze (o della frequenza) di ciascun colore.
La distribuzione può essere calcolata separatamente per
ciascun canale (RGB, HSV, …) o globalmente ottenendo un
istogramma in 3 dimensioni
Calcolo distribuzione dei colori
Vediamo come calcolare la distribuzione dei colori di ciascun canale
usando la funzione “imhist” di matlab:
%carico l'immagine da disco
I = imread('foto.png');
%costruisco l'istogramma dei colori dei singoli canali
nbins = 15;
for idx=[1:3],
h{idx} = imhist(I(:,:,idx), nbins);
%calcolo le frequenze dei colori
h{idx} = h{idx} / sum(h{idx});
end
%plot
figure(1);
subplot(1,4,1); imshow(I);
for idx=[1:3],
subplot(1,4, 1+idx); bar(h{idx});
end
Calcolo distribuzione dei colori
Matlab non fornisce funzioni predefinite per il calcolo dell'istogramma
dei colori in 3 dimensioni, per cui sarà necessario costruire una
funzione specifica.
function h3D = imColorHist(I, nbins)
% Calcola istogramma dei colori 3D per immagini
% con tre livelli in [0:255]
if nbins>256, nbins =256; end;
h3D = zeros(nbins,nbins,nbins);
h3D = zeros(nbins,nbins,nbins);
for r=[1:size(I,1)],
for c=[1:size(I,2)],
%Estraggo la terna RGB in vettore
v = I(r,c,:);
%
rQ
gQ
bQ
end
end
Quantizzo i valori e trasformo in indici (>=1)
= min(fix(nbins* double(v(1))/255), nbins-1)+1;
= min(fix(nbins* double(v(2))/255), nbins-1)+1;
= min(fix(nbins* double(v(3))/255), nbins-1)+1;
h3D(rQ, gQ, bQ) = h3D(rQ, gQ, bQ)+1;
%h3D=reshape(h3D, [numel(h3D),1]);
return;
Calcolo distribuzione dei colori
La funzione di quantizzazione deve ricampionare i livelli di colore
nell'intervallo [0:NBINS-1].
La funzione ValQ = fix(nbins* Val/255) distribuisce equamente tutti
valori in [0:NBINS-1] tranne val=255, pertanto è necessario aggiungere
un controllo sul valore massimo.
La formula finale diverrà:
ValQ = min(fix(nbins* Val/255),nbins-1);
Per ottenere gli indici dei vettori (>=1) è sufficiente sommare 1
Calcolo distribuzione dei colori
Vediamo lo stesso codice in una versione ottimizzata, che sfrutta la
capacità di matlab di lavorar con le matrici.
function h3D = imColorHist(I, nbins)
% Calcola istogramma dei colori 3D per immagini
% con tre livelli in [0:255]
if nbins>256, nbins =256; end;
h3D = zeros(nbins,nbins,nbins);
% Quantizzo i valori
Iq = fix(double(I) * nbins/255); % per I=255 ottengo Iq =nbins
Iq = min(Iq, nbins-1); % impongo valore massimo a nbins-1
Iq = Iq+1
% Trasformo in indici (>= 1)
for r=[1:size(I,1)],
for c=[1:size(I,2)],
%Estraggo la terna quantizzata RGB in vettore
v = Iq(r,c,:); %rQ = v(1); gQ = v(2); bQ = v(3);
end
end
h3D(v(1), v(2), v(3)) = h3D(v(1), v(2), v(3))+1;
%h3D=reshape(h3D, [1, numel(h3D)]); %trasformo in vettore riga
return;
Calcolo distribuzione dei colori
Nel caso dello spam la distribuzione dei colori contiene più informazioni
di quelle necessarie, il che potrebbe essere anche fonte di errori.
Per questo problema può bastare contare il numero di colori diversi
(numero elementi diversi da zero nell'istogramma) e/o valutare se e in
che quantità è presente un colore molto comune (il massimo
dell'istogramma)
%carico l'immagine da disco
I = imread('foto.png');
%considero l'immagine a livelli di grigi
G = rgb2gray(I);
histGL = imhist(G); histGL = histGL /sum(histGL);
numColors = sum(histGL >0);
%numColors = numel(unique(unique(G))); %conto i valori unici
firstColorFreq = max(histGL);
Estrazione Wavelet
In termini molto generali l'analisi wavelet 2D è un metodo di analisi
delle immagini nello spazio delle frequenze, in cui l’immagine corrente
viene decomposta in più immagini, ciascuna delle quali mostra dettagli
in scala crescente (secondo le direzioni verticali e/o orizzontali), che
permettono una analisi a multi-risoluzione dell’immagine iniziale.
Tramite le wavelet (come per FFT
DCT) è possibile ottenere
informazioni sul contenuto in
frequenza di una immagine e quindi
sulle texture.
HL
LH
HH
Estrazione Wavelet
Matlab mette a disposizione, tramite il toolbox di image processing,
una funzione per il calcolo della trasformata wavelt discreta DWT
%carico l'immagine da disco
I = imread('foto.png');
G = rgb2gray(I); % converto a livelli di girgio
%dwt primo livello
[cDW1,cLH1,cHL1,cHH1] = dwt2(double(G),'haar');
figure(1);
imagesc([cDW1,cHL1; cLH1,cHH1]);
colormap('gray')
% dwt secondo livello
[cDW2,cLH2,cHL2,cHH2] = dwt2(cDW1,'haar');
figure(2);
tmp1 = [cDW2 cHL2; cLH2 cHH2];
if any(size(tmp1) ~= size(cDW1)),
tmp1 = tmp1(1:size(cDW1,1), 1:size(cDW1,2));
end
imagesc([tmp1, cHL1; cLH1,cHH1]);
colormap('gray');
Estrazione Wavelet
In alternativa è possibile scaricare da internet funzioni create da altri
utenti.
Consideriamo il codice prelevato da (link):
www.mathworks.com/matlabcentral/fileexchange/
11133-wavelet-transforms-in-matlab
WAVELET Discrete wavelet transform.
Y = WAVELET(W,L,X)
computes the L-stage discrete wavelet transform (DWT)
of signal X using wavelet W. The length of X must be
divisible by 2^L. For the inverse transform,
WAVELET(W,-L,X) inverts L stages.
...
Exemple:
Y = wavelet('2D CDF 9/7',2,X);
Estrazione Wavelet
%carico l'immagine da disco
I = imread('foto.png');
G = double(rgb2gray(I));
% converto a livelli di girgio
dwtLevels = 1;
cropSize = fix([size(I,1) size(I,2)]/2^dwtLevels) …
*(2^dwtLevels);
imgDWT = wavelet('2D Le Gall 5/3', dwtLevels, …
G(1:cropSize(1), 1:cropSize(2),1));
figure(1)
imagesc(imgDWT);
colormap('gray');
Estrazione Wavelet
Consideriamo il risultato della trasformata wavelet, in
alcuni casi è necessario poter estrarre i singoli canali
dall'immagine completa
HL
LH
HH
Estrazione Wavelet
% Per ciasucn livello l recupero le sottoimmagini
k=1;
dwtChannels={};
for l=1:dwtLevels
rDim = size(imgDWT,1) / (2^l); % numero righe sottoimmagine
rEND = size(imgDWT,1) / (2^(l-1)); % ultima riga livello
%(fine sottoimmagine 3)
rMDL = rEND-rDim; % riga punto centrale livello
%(inizio sottoimmagine 3)
cDim = size(imgDWT,2) / (2^l); % numero colonne sottoimmagine
cEND = size(imgDWT,2) / (2^(l-1)); % ultima colonna livello
cMDL = cEND-cDim; % colonna punto centrale livello
end
dwtChannels{k} = imgDWT(
1:rMDL, cMDL+1:cEND); k=k+1;%HL
dwtChannels{k} = imgDWT(rMDL+1:rEND,
1:cMDL); k=k+1;%LH
dwtChannels{k} = imgDWT(rMDL+1:rEND, cMDL+1:cEND); k=k+1;%HH
if(l == dwtLevels)
dwtChannels{k} = imgDWT(1:rMDL, 1:cMDL); k=k+1; %LL
end
Dataset
Tipicamente, durante lo sviluppo del proprio sistema di classificazione,
non è conveniente estrarre ad ogni simulazione le feature dai
campioni.
L'approccio miglio consiste nell'estrarre le feature da tutti campioni a
disposizione e costruire una raccolta di pattern con le relative etichette
di classe denominato dataset.
Tipicamente un dataset è costituito
da una matrice delle feature, in cui
ogni riga rappresenta un pattern ed
ogni colonna una singola feature, e
da un vettore colonna contenete le
etichette di classe (labels)
tipicamente rappresentate da
numeri interi.
feature h
labels
1
1
1
2
2
2
pattern k
1
2
2
Esempio costruzione dataset
Consideriamo il problema di riconoscimento delle immagini di spam e
di avere a disposizione una serie di immagini pre-etichettate su disco
divise in due cartelle: 'spam' ed 'ham'.
Supponiamo di voler estrarre le feature: numero dei livelli di grigio,
rapporto dimensioni immagini, logaritmo del numero di pixel.
Nota1: si consiglia di creare un funzione che dato il nome dell'immagine restituisca il
vettore riga delle features
function pattern = extractFeatures1(nomeFile)
ImgRGB = imread(nomeFile);
....
....
pattern = [numColori, numPixel, aspectRatio];
return;
Nota2: Utilizziamo la funzione “dir” per avere l'elenco dei file in una cartella
Es:
dirClass1 = 'dataset/spam_imgset/trn/spam';
listFileName1 = dir([dirClass1 '/*.png']);
....
fileName = [dirClass1 '/' listFileName1(idx).name];
....
pattern = extractFeatures1(fileName)
....
Esempio costruzione dataset
function pattern = extractFeatures1(nomeFile)
imgRGB = imread(nomeFile);
imgGL = rgb2gl(imgRGB);
numColori = numel(unique(unique(imgGL)));
numPixel = log(numel(imgGL));
apectRatio = size(imgGL,1)/size(imgGL,2);
pattern = [numColori, numPixel, aspectRatio];
return;
Esempio costruzione dataset
function [featureMat labels] = createDataset(dirClass1, dirClass2)
listFileName1 = dir([dirClass1 '/*.png']);
numFiles1 = length(listFileName1);
listFileName2 = dir([dirClass2 '/*.png']);
numFiles2 = length(listFileName2);
numFeatures=3;
featureMat = zeros(numFiles1+numFiles2, numFeatures);
labels
= zeros(numFiles1+numFiles2, 1);
iPatt = 1;
for idx=[1:numFiles1]
fileName = [dirClass1 '/' listFileName1(idx).name];
featureMat(iPatt,:) = extractFeatures(fileName);
labels(iPatt) = 1;
iPatt = iPatt +1;
end
for idx=[1:numFiles2]
fileName = [dirClass2 '/' listFileName2(idx).name];
featureMat(iPatt,:) = extractFeatures(fileName);
labels(iPatt) = 2;
iPatt = iPatt +1;
end
return