Classificazione automatica applicata alle immagini

In questo capitolo viene mostrato un esempio di applicazione di una
tecnica kernel di classificazione automatica supervisionata alla
detection di pattern nelle immagini, in particolare l'esempio mostra una
bozza di possibile algoritmo di localizzazione delle targhe (algoritmo
assolutamente migliorabile da molti punti di vista tra cui sicuramente
robustezza e tempo di calcolo). La metodologia mostrata consiste
nell'apprendere delle caratteristiche locali delle porzioni di immagini
contenenti targhe, per poi "scansionare" l'intera immagine costruendo un
insieme di vettori di caratteristiche da classficare. Il classificatore
kernel utilizzato è K-IPCAC: see "Novel Fisher discriminant classifiers".

Contents

Estrazione delle caratteristiche

In questo esempio di applicazione le caratteristiche estratte riguardano
luminosità e contrasto, in particolare vengono utilizzate l'immagine
originale e la versione filtrata tramite la derivata della gaussiana,
questo per apprendere la presenza di regioni chiare e regioni scure,
nonché la presenza di forti bordi. Gli esempi vengono estratti da una
immagine contenente 2 targhe, ogni regione è un quadrato di lato fissato
i cui livelli di grigio contenuti vengono utilizzati per calcolare le
features, questo metodo ci permette di raccogliere molti esempi negativi
e un certo numero di esempi positivi.
% Init:
img = imtype(imread('training.jpg'),'gf');
img1 = imscale(gaussianDerivative(img));
rad = 10;
samples = [];
classification = false(0,0);
hx = 0.05:0.1:0.95;
load rects;

% Estraggo le features:
for x=1:rad:size(img,2)-2*rad-1
    for y=1:rad:size(img,1)-2*rad-1
        % Ottengo la patch:
        patch = img(y:y+2*rad,x:x+2*rad);
        patch1 = img1(y:y+2*rad,x:x+2*rad);

        % Estraggo le features su questa patch:
        features = hist(patch,hx); features = features/sum(features);
        features1 = hist(patch1,hx); features1 = features1/sum(features1);

        % Salvo l'esempio:
        samples = [samples,[features(:);features1(:)]];

        % Decido se positivo o negativo:
        if (pointinrect(rect1,[x;y]) && pointinrect(rect1,[x;y]+2*rad+1)) || ...
           (pointinrect(rect2,[x;y]) && pointinrect(rect2,[x;y]+2*rad+1))
            % Esempio positivo:
            classification = [classification,true];
        else
            % Esempio negativo:
            classification = [classification,false];
        end
    end
end

Vediamo le regioni considerate positive:

figure; imshow(img); hold on;
for x=1:rad:size(img,2)-2*rad-1
    for y=1:rad:size(img,1)-2*rad-1
        % Decido se positivo o negativo:
        if (pointinrect(rect1,[x;y]) && pointinrect(rect1,[x;y]+2*rad+1)) || ...
           (pointinrect(rect2,[x;y]) && pointinrect(rect2,[x;y]+2*rad+1))
            plotrect([x,y,2*rad,2*rad]);
        end
    end
end

Effettuiamo l'addestramento utilizzando l'algoritmo KIPCAC:

% Versione lineare:
% net = OIPCAClearn(samples,classification);

% Versione kernel:
net = KIPCAClearn(samples,classification);

Testing

A tempo di testing una nuova immagine viene fornita al sistema,
l'estrazione di caratteristiche avviene nella stessa maniera con la
differenza che non esiste conoscenza a priori di dove sia localizzata la
targa.
% Init:
img2 = imtype(imread('testing.jpg'),'gf');
img3 = imscale(gaussianDerivative(img2));
rad = 10;
samples2 = [];
hx = 0.05:0.1:0.95;

% Estraggo le features:
for x=1:rad:size(img2,2)-2*rad-1
    for y=1:rad:size(img2,1)-2*rad-1
        % Ottengo la patch:
        patch = img2(y:y+2*rad,x:x+2*rad);
        patch1 = img3(y:y+2*rad,x:x+2*rad);

        % Estraggo le features su questa patch:
        features = hist(patch,hx); features = features/sum(features);
        features1 = hist(patch1,hx); features1 = features1/sum(features1);

        % Salvo l'esempio:
        samples2 = [samples2,[features(:);features1(:)]];
    end
end
Effettuiamo la classificazione su tutti i vettori di caratteristiche
estratti sull'immagine per identificare le zone di targa:
% Versione lineare:
% sclass = OIPCACclassify(net,samples2);

% Versione kernel:
sclass = KIPCACclassify(net,samples2);

Vediamone il risultato:

figure; imshow(img2); hold on;
n = 1;
for x=1:rad:size(img2,2)-2*rad-1
    for y=1:rad:size(img2,1)-2*rad-1
        if sclass(n)
            plotrect([x,y,2*rad,2*rad]);
        end
        n = n + 1;
    end
end