161
Appendice A
In questa appendice viene riportato il codice, implementato su Matlab®, dell’algoritmo utilizzato per la stima dei parametri della funzione di emissione dei LED utilizzati. La curva utilizzata per il fitting è di tipo sigmoidale e presenta 4 parametri. Questi ultimi sono stati calcolati con un algoritmo di tipo brute-force dato che non era possibile ottenere dei valori a priori dei parametri. In uscita è fornito il valore dei quattro parametri e l’errore quadratico medio rispetto alla curva riportata sul datasheet.
%%% CALCOLO PER STIMA AI MINIMI QUADRATI DEI PARAMETRI DELLA FUNZIONE
%%% SIGMOIDE DI EMISSIONE DEL LED %%%
close all clear all
% Vado a inserire i dati ottenuti dal grafico di emissione del LED presente
% nel datasheet fornito dal costruttore
Rel_luminosity = [0.026 0.051 0.104 0.156 0.208 0.273 0.312 0.351 0.402 0.454 0.506 0.558 0.610 0.662 0.701 0.753 0.805 0.844 0.896 0.948 1];
Angoli = [1.575 1.49 1.41 1.35 1.29 1.25 1.19 1.15 1.09 1.05 0.97 0.93 0.85 0.80 0.74 0.68 0.58 0.52 0.42 0.30 0];
figure, plot(Angoli, Rel_luminosity, '-b'), title('Andamento della Luminosità relativa in funzione angolo come da datasheet'),...
xlabel('angolo di emissione (rad)'), ylabel('Luminosità relativa');
% Inizializzo i margini di variabilità dei miei quattro parametri della
% funzione sigmoide a = (-10:0.1:10);
c = (-10:0.1:10);
b = (-10:0.1:10);
d = (-0.5: 0.01:0.5);
N = length(a);
NN = length(c);
NNN = length(b);
NNNN = length(d);
% Parto con l'algoritmo di ricerca esaustiva del minimo errore quadratico
% medio
mse = inf; % inizializzo il valore iniziale dell'errore quadratico medio for i = 1:N
for j = 1:NN
162
for z = 1:NNN for x = 1:NNNN
% Calcolo il vettore dei valori assunti dalla funzione sigmoide con i valori attuali dei parametri
H = b(z) * sigmf (Angoli, [a(i), c(j)]) + d(x);
% calcolo le differenze tra valori sperimentali e teorici e poi
% elevo al quadrato la differenza Diff = Rel_luminosity - H;
Diff = Diff.^2;
D = length(Diff);
err = sum(Diff);
err = err/D;
% Noto l'errore quadratico medio di questa funzione sigmiode con i valori attuali dei parametri a(i) e c(j). Vado adesso a vedere se tale valore è inferiore a quelli ottenuti in precedenza
if (err < mse)
mse = err; % aggiorno l'errore quadratico medio minimo a_stim = a(i); % salvo il valore del parametro a
c_stim = c(j); % salvo il valore del parametro c b_stim = b(z); % salvo il valore del parametro b d_stim = d(x); % salvo il valore del parametro d H_stim = H;
% salvo il valore della funzione stimata sugli angoli noti end
end end end end
% Visualizzo i risultati
figure, plot (Angoli, H_stim, '-b'), hold on, plot(Angoli, Rel_luminosity, '- r'), title('Andamento Luminosità relativa stimato vs valori relali'),...
legend('Curva stmata','Curva Sperimentale'), xlabel('Angolo di emissione (rad)'), ylabel('Luminosità relativa');
display (['Errore quadratico medio commesso è ' num2str(mse)]);
display (['I valori dei parametri sono: a = ' num2str(a_stim) '; b = ' num2str(b_stim) '; c = ' num2str(c_stim) ' ; d = ' num2str(d_stim)]);
Nel capitolo tre vengono presentati e discussi i risultati di questo algoritmo.
163
Appendice B
In questa appendice vengono riportati i modelli del sistema di illuminazione implementati in Matlab®. Le quattro configurazioni dei LED testate vengono riportate in sequenza. I risultati ottenuti sono analizzati e visualizzati nel capitolo tre.
1) Modello a sei LED in configurazione lineare
%%% PRIMA PROVA: analisi del sistema di illuminazione composto da 6 LED.
%%% Viene considerata la direttività funzionale del LED. Inoltre è
%%% utilizzata la configurazione a 6 LED più semplice.
close all clear all
% Inizializzo una matrice tridimensionale che sarà il mio spazio di lavoro
% in cui ogni cella della matrice equivale ad un cubo di 2 mm di lato space = zeros (80, 120, 80);
% Inizializzo i parametri del LED e nel mezzo di propagazione (acqua)
% Ipotizzo una attenuazione esponenziale, che il mezzo sia omogeneo e si
% tratti solo di acqua. Non considero né riflessioni, né rifrazioni né
% scattering, ma solo l'assorbimento del mezzo
I0 = 1000; % Intensità emessa dal LED misurata in millicandele (mcd) coeff_abs = -0.00001;
% coefficiente assorbimento dell'anidride carbonica. Tale valore corrisponde ad
%una approssimazione in quanto lo spettro di emissione del LED è stato
%approssimato alla sola componente maggioritaria e quindi tale coefficiente di
%assorbimento equivale alla sola lunghezza d'onda di 600 mm.
% Parametri della funzione sigmoide di emissione stimata precedentemente.
% Tale funziona approssima la direttività di emissione luminosa del LED
% utilizzato.
a_par = -2.9;
b_par = 1.3;
c_par = 1.1;
d_par = -0.25;
% Inizializzo la posizione dei LED: visti come sorgenti puntuali di luce,
% con un proprio angolo verticale e orizzontale di irraggiamento e con una
% emissione continua a intensità costante (calcolata come valore medio nel datasheet).
% Da notare che le posizioni delle due videocamere adesso sono (40,53,1) e
% (40,47,1). (ho imposto una distanza tra le due aperture delle videocamere
% di 5 celle, cioè dispari, per avere una cella centrale alla quale
% riferire il fov stereoscopico).
X = [52 57 62 62 57 52];
164
Y = [43 43 43 37 37 37];
Z = [1 1 1 1 1 1];
% Analisi dell'Intensità. Come ipotesi di lavoro considero che le intensità
% in ogni punto derivanti dai diversi LED si sommino, quindi è trascurata
% la natura ondulatoria della luce che avrebbe costretto ad una analisi di
% interferenza delle singole onde luminose generate.
% Analisi dell'Intensità. Come ipotesi di lavoro considero che le intensità
% in ogni punto derivanti dai diversi LED si sommino, quindi è trascurata
% la natura ondulatoria della luce che avrebbe costretto ad una analisi di
% interferenza delle singole onde luminose generate.
for h = 1:6
space (Y(h), X(h), Z(h)) = I0;
for i = 1:80 for j = 1:120 for z = 2:80
% Calcolo gli angoli tra punto considerato e emettitore alfa = atan ( (j - X(h)) / (z - Z(h)) );
theta = atan ( (i - Y(h)) / (z - Z(h)) );
% Rendo i due angoli positivi per poi poter utilizzare la funzione sigmf.
if (alfa < 0)
alfa = alfa * (-1);
end
if (theta < 0)
theta = theta * (-1);
end
% Calcolo il valore dell'intensità in funzione dell'angolo orizzontale e verticale secondo una funzione sigmoide ricavata dal datasheet
distanza1 = (2*i - 2*Y(h))^2 + (2*j - 2*X(h))^2 + (2*z - 2*Z(h))^2;
distanza = sqrt (distanza1);
space (i, j, z) = space (i, j, z) + I0 * exp (coeff_abs * distanza)*...
( b_par * sigmf (theta, [a_par c_par]) + d_par ) * ( b_par * sigmf (alfa, [a_par c_par] + d_par) );
end
end end end
% Visualizzazione dei Risultati.
% Viene visualizzato l'andamento dell'intensità luminosa all'interno del
% campo di vista stereoscopico.
% Dal datasheet delle telecamere è possibile individuare, con una lunghezza
% focale di 3.1 mm, ovvero quella che comunemente utilizzo, un angolo di
% apertura orizzontale di 65° 39' = 65,65° (1.148875 rad)e un angolo di
% apertura verticale di 52° 50' = 52.835° (0.9246125 rad). Le videocamera
% sono in posizione (40,57,1) e (40,63,1) secondo la configurazione dei
% LED schelta. Il FOV stereoscopico è dato da un'apertura di 65,59° e con
% shift in profondità di 6.75 mm (vedi calcoli quaderno). Tale
% FOV è centrato quindi nel punto di mezzo tra le due videocamere.
dist_vis = [20 30 40 50 70 80 100 110 130 150];
% vettore con le profondità che voglio visualizzare N = length(dist_vis);
Campo_visivo = zeros(80, 120, N);
dim_oriz = zeros (1,N);
% vettore per salvare le dimensioni reali del FOV
165
dim_vert = zeros (1,N);
% vettore per salvare le dimensioni reali del FOV oriz_ster = zeros (1,N);
% vettore di appoggio per salvare le dimensioni del FOV stereoscopico vert_ster = zeros (1,N);
% vettore di appoggio per salvare le dimensioni del FOV stereoscopico oriz_st = zeros (1, N);
% vettore di appoggio per salvare la dimensione orizzontale del FOV della
% videocamera alle varie profondità.
vert_st = zeros (1, N);
% vettore di appoggio per salvare la dimensione verticale del FOV della
% videocamera alle varie profondità.
for u = 1:N
% calcolo le dimensioni effettive, orizzontali e verticali, del campo di
% vista di ogni videocamera, a quella data distanza dim_oriz(u) = 2*dist_vis(u)*tan(1.148875/2);
dim_vert(u) = 2*dist_vis(u)*tan(0.9246125/2);
% Calcolo la dimensione del FOV stereoscopico a questa stessa profondità.
oriz_ster(u) = 2 * (dist_vis(u) - 6.75) * tan(1.148875/2);
vert_ster(u) = 2 * (dist_vis(u) - 6.75) * tan(0.9246125/2);
% Eseguo le stesse operazioni di approssimazione eseguite anche precedentemente.
oriz_st(u) = round (oriz_ster(u)/2);
vert_st(u) = round (vert_ster(u)/2);
if ( mod(oriz_st(u), 2) == 0 ) % se è pari oriz_st(u) = oriz_st(u) +1;
end
if ( mod(vert_st(u), 2) == 0 ) % se è pari vert_st(u) = vert_st(u) +1;
end
% Costruisco una matrice che ha 1 in corrispondenza del campo di vista
% stereocopico alla profondità data. Ricordare che l'origine del campo
% di vista stereoscopico è in posizione (40,60,1). Gli estremi sono stati resi dispari in modo da centrarli e quindi occorre approssimarli con la funzione fix
% ad un intero.
H_FOV = space ( (40 - fix(vert_st(u) /2)):(40 + fix(vert_st(u) /2)), (57 - fix(oriz_st(u) /2)):(57 + fix(oriz_st(u) /2)) );
% Per poter visualizzare contemporaneamente il campo visivo stereoscopico e
% l'andamento dell'intensità luminosa ad uno stesso piano di profondità
% è però necessario andare a calcolare il valore massimo di intensità a
% tale profondità e fornire tale valore (leggermente incrementato) al
% grafico del campo visivo per fare in modo che "emerga" dal secondo
% grafico.
MAX = max(space (:,:, dist_vis(u)/2));
M = max (MAX);
% Vado poi a costruire la matrice con il Campo Visivo stereoscopico;
% che sarà centrato sulla cella corrispondente alla telecamera (40, 57) Campo_visivo ( (40 + fix(vert_st(u)/2)), (57 - fix(oriz_st(u)/2)):(57 + … fix(oriz_st(u)/2)), u ) = M + 50;
Campo_visivo ( (40 - fix(vert_st(u)/2)), (57 - fix(oriz_st(u)/2)):(57 + … fix(oriz_st(u)/2)), u ) = M + 50;
166
Campo_visivo ( (40 - fix(vert_st(u)/2)): (40 + fix(vert_st(u)/2)), (57 + … fix(oriz_st(u)/2)), u ) = M + 50;
Campo_visivo ( (40 - fix(vert_st(u)/2)): (40 + fix(vert_st(u)/2)), (57 - … fix(oriz_st(u)/2)), u ) = M + 50;
% Visualizzo i risultati ottenuti: a sinistra è mostrato il campo di
% vista stereoscopico, mentre a destra l'andamento dell'intensità
% luminosa con sovrapposto il campo di vista stereosopico
figure, subplot(1, 2, 1), imagesc(Campo_visivo(:, :, u)), title (['Campo visivo stereoscopico alla profondità ' num2str(dist_vis(u))]);
subplot(1, 2, 2), mesh(space (:,:, dist_vis(u)/2)), hold on, mesh(Campo_visivo (:, :, u)),...
xlabel('distanza (mm)'), ylabel('distanza (mm)'), zlabel('Intensità Luminosa (mcd)'),...
title(['Andamento di intensità luminosa alla profontià ' num2str(dist_vis(u)) 'con sovrapposto il campo visivo stereoscopico']);
% Visualizzo l'andamento dell'intensità luminosa nel solo campo di
% vista stereoscopico figure,...
mesh((57 - oriz_st(u)/2):(57 + oriz_st(u)/2), (40 - vert_st(u)/2):(40 + vert_st(u)/2), space((40 - vert_st(u)/2):(40 + vert_st(u)/2), (57 - oriz_st(u)/2):(57 + oriz_st(u)/2), dist_vis(u)/2)),...
title (['Andamento intensità luminosa interno al campo di vista stereoscopico alla profondità di ' num2str(dist_vis(u)) ' mm']),...
zlabel('intensità in mcd'), xlabel('distanza orizzontale in 2mm'), ylabel('distanza verticale in 2mm');
end
% Analisi dell'uniformità dell'illuminazione: calcolo del numero di punti all'interno del campo di vista stereoscopico con Coefficiente di Variazione inferiore al 5% Il coefficiente di variazione è definito come il raporto tra la
% deviazione dalla media del valore puntuale e la media dei valori di
% luminosità.
CV = zeros(1,N);
% Vettore di appoggio sul quale salverò i valori del numero di punti
% con coefficiente di variazione inferiore al 5% per ogni valore di profondità mean = zeros (1,N);
% Vettore di appoggio nel quale salverò il valore medio di intensità luminosa al varire della profondità.
for u = 1 : N
profondita = dist_vis (u);
% Carico i valori della dimensione del campo di vista stereoscopico alla profondità corrente
oriz = oriz_st (u);
vert = vert_st (u);
% La matrice che corrisponde ai valori di intensità luminosa
% all'interno del campo di vista stereoscopico è dunque ricavabile
% grazie agli estremi ricavati. Tali estremi sono stati resi dispari in
% modo da centrarli e quindi occorre approssimarli con la funzione fix
% ad un intero.
H = space((40 - fix(vert/2)):(40 + fix(vert/2)), (57 - fix(oriz/2)):(57 + fix(oriz/2)), dist_vis(u)/2);
% Calcolo il valore medio dell'intensità luminosa all'interno del campo
167
% di vista appena costruito [L K] = size (H);
S = sum (H);
St = sum (S);
mean(u) = St / (L * K);
H1 = zeros (L, K); % matrice di appoggio per i valori di CV CV_image = zeros (L,K); % matrice di appoggio per la visualizzasione int = 0; % contatore del numero di punti con CV ottimale
for i = 1 : L for j = 1 : K
H1 (i, j) = (H(i, j) - mean(u)) / mean(u);
end end
% Conteggio e visualizzazione dei punti del FOV con CV < 5%
for i = 1 : L for j = 1 : K
if ( (H1(i,j) >= -0.05)&& (H1(i,j) <= 0.05)) CV_image(i,j) = H1 (i,j);
int = int + 1;
end end end
CV(u) = int / (L * K);
% Visualizzazione delle mappe del Coefficiente di Variazione inferiore a 5% nel FOV stereoscopico
figure, imagesc(CV_image), title(['Punti del FOV con CV inferiore al 5% alla distanza di ' num2str(dist_vis(u)) ' mm']),colorbar('EastOutside');
figure, surf(H), colormap('jet'), shading('interp'),...
xlabel('distanza (mm)'), ylabel('distanza (mm)'), zlabel('Intensità Luminosa (mcd)'),...
title(['Intensità luce nel campo di vista stereoscopico alla distanza di ' num2str(dist_vis(u)) ' mm']),...
colorbar('EastOutside');
end
% Visualizzo l'andamento con la profondità del numero di punti con CV < 5%
figure, plot (dist_vis(1), CV (1), '.r',dist_vis(2), CV (2), '.r', dist_vis(3), CV (3), '.r',...
dist_vis(4), CV (4), '.r', dist_vis(5), CV (5), '.r', dist_vis(6), CV (6), '.r',...
dist_vis(7), CV (7), '.r', dist_vis(8), CV (8), '.r', dist_vis(9), CV (9), '.r',...
dist_vis(10), CV (10), '.r'),...
title('Andamento della Percentuale del FOV che ha CV minore del 5%'),...
xlabel('Profondità (mm)'), ylabel('Percentuale FOV');
% Visualizzo l'andamento della media intensità luminosa
figure, plot (dist_vis(1), mean (1), '.r', dist_vis(2), mean (2), '.r', dist_vis(3), mean (3), '.r',...
dist_vis(4), mean (4), '.r', dist_vis(5), mean (5), '.r', dist_vis(6), mean (6), '.r',...
dist_vis(7), mean (7), '.r', dist_vis(8), mean (8), '.r', dist_vis(9), mean (9), '.r',...
dist_vis(10), mean (10), '.r'),...
title('Andamento intensità luminosa media nel campo di vista stereoscopico'),...
xlabel('Profondità (mm)'), ylabel('Intensità Luminosa (mcd)');
168
% Analisi uniformità dell'illuminazione. Viene calcolata la deviazione
% standard della distribuzione della luce. Di fatto si approssima difatti
% la distribuzione della luce ad una gaussiana.
std_oriz = zeros(1, N);
% vettore di appoggio sul quale memorizzerò i valori di deviazione
% standard orizzontale ottenuti con il modello std_vert = zeros(1, N);
% vettore di appoggio sul quale memorizzerò i valori di deviazione
% standard verticale ottenuti con il modello
for y = 1:N
% Costruisco la matrice che rappresenta la distribuzione dell'intensità
% luminosa nel campo di vista della videocamera. Le dimensioni del FOV
% le ricavo dai vettori precedentemente generati.
oriz = oriz_st(y);
vert = vert_st(y);
H = space((40 - fix(vert/2)):(40 + fix(vert/2)), (57 - fix(oriz/2)):(57 + fix(oriz/2)), dist_vis(y)/2);
% Estraggo due vettori corrispondenti alla riga e alla colonna centrale
% di tale matrice (e quindi del campo di vista).
o = fix (oriz/2) + 1; % fix approssima all'intero inferiore v = fix (vert/2) + 1;
distr_oriz = H(v,:);
distr_vert = H(:,o);
% Visualizzo le distribuzioni orizzontali e verticali
figure, subplot(1, 2, 1), plot (distr_oriz, 'r'), ylabel('Intensità luminosa (mcd)'),...
xlabel('distnza (mm)'), title ([ 'Distribuzione orizzontale a ' num2str(dist_vis(y)) ' mm' ]);
subplot(1, 2, 2), plot (distr_vert, 'b'), ylabel('Intensità luminosa (mcd)'),...
xlabel('distnza (mm)'), title ([ 'Distribuzione verticale a ' num2str(dist_vis(y)) ' mm' ]);
% calcolo del valore medio per normalizzare il valore delle deviazioni
% standard.
mean_oriz = sum(distr_oriz);
mean_oriz = mean_oriz / length(distr_oriz);
mean_vert = sum(distr_vert);
mean_vert = mean_vert / length(distr_vert);
% Calcolo i valori di deviaizone standard e li memorizzo std_oriz (y) = std (distr_oriz) / mean_oriz;
std_vert (y) = std (distr_vert) / mean_vert;
end
% Visualizzo l'andamento delle due deviazioni standard ricavate
figure, plot (dist_vis(1), std_oriz (1), '.r',dist_vis(2), std_oriz (2), '.r', dist_vis(3), std_oriz (3), '.r',...
dist_vis(4), std_oriz (4), '.r', dist_vis(5), std_oriz (5), '.r', dist_vis(6), std_oriz (6), '.r',...
dist_vis(7), std_oriz (7), '.r', dist_vis(8), std_oriz (8), '.r', dist_vis(9), std_oriz (9), '.r',...
169
dist_vis(10), std_oriz (10), '.r'),...
title('Andamento della deviazione standard normalizzata orizzontale'),...
xlabel('Profondità (mm)'), ylabel('Deviazione standard normalizzata');
figure, plot (dist_vis(1), std_vert (1), '.r',dist_vis(2), std_vert (2), '.r', dist_vis(3), std_vert (3), '.r',...
dist_vis(4), std_vert (4), '.r', dist_vis(5), std_vert (5), '.r', dist_vis(6), std_vert (6), '.r',...
dist_vis(7), std_vert (7), '.r', dist_vis(8), std_vert (8), '.r', dist_vis(9), std_vert (9), '.r',...
dist_vis(10), std_vert (10), '.r'),...
title('Andamento della deviazione standard normalizzata verticale'),...
xlabel('Profondità (mm)'), ylabel('Deviazione standard normalizzata');
% Analisi dell'intensità minima di illuminazione ottenuta. In questo caso
% si considera che, da datasheet, le videocamere richiedono una
% illuminazione minima di 1,5 lux. Purtroppo il nostro modello è in mcd e
% quindi occorre prima convertirlo. Tale analisi viene fatta sul campo di
% vista di ogni videocamera singola, solamente alla fine viene verificato
% il superamento del valore minimo all'interno del campo di vista
% stereoscopico.
% costruisco due matrici di appoggio con le distanze di ogni punto dello
% spazio dalle due videocamere singolarmnete.
distanza1 = zeros (80, 120, 79); % matrice distanze dalla prima videocamera distanza2 = zeros (80, 120, 79); % matrice distanze dalla seconda videocamera
% Calcolo distanze for i = 1:80
for j = 1:120 for z = 2:80
% Calcolo distanza dalla prima videocamera (posizione 40, 57).
distanz = (2*i - 2*40)^2 + (2*j - 2*54)^2 + (2*z - 2*1)^2;
distanza1(i, j, z) = sqrt(distanz);
% Calcolo distanza dalla seconda videocamera (posizione 40, 63).
distanz = (2*i - 2*40)^2 + (2*j - 2*60)^2 + (2*z - 2*1)^2;
distanza2(i, j, z) = sqrt(distanz);
end
end end
% Per convertire le candele in lux occorre calcolare l'angolo steradiante
% corrispondente ad ogni punto. Si sfrutta quindi il fatto che ogni cella
% ha un'area fissa pari a 4 mm2.
% L'angolo steradiante viene però calcolato facilmente solo per un cono
% mentre in questo caso la figura solida generata sarebbe quella di una
% piramide a base quadrata. Per calcolare l'approssimazione effettuata si
% calcolano i due volumi e se ne fa il rapporto.
% Matrici di appoggio per la prima videocamera vol_pir_v1 = zeros (80, 120, 79);
% matrice in cui salverò i volumi piramidali corrispondenti.
vol_con_v1 = zeros (80, 120, 79);
% matrice in cui salverò i volumi conici corrispondenti.
appros_v1 = zeros (80, 120, 79); % matrice di appoggio approssimazioni.
170
ang_ap_v1 = zeros (80, 120, 79);
% matrice con i corrispondenti angoli di apertura dei coni.
sterad_v1 = zeros (80, 120, 79);
% matrice che contiene l'angolo solido corrispondente ad ogni punto.
lux_v1 = zeros (80, 120, 79);
% matrice in cui salverò i valori in lux di illuminazione.
% Matrici di appoggio per la seconda videocamera vol_pir_v2 = zeros (80, 120, 79);
% matrice in cui salverò i volumi piramidali corrispondenti.
vol_con_v2 = zeros (80, 120, 79);
% matrice in cui salverò i volumi conici corrispondenti.
appros_v2 = zeros (80, 120, 79); % matrice di appoggio approssimazioni.
ang_ap_v2 = zeros (80, 120, 79);
% matrice con i corrispondenti angoli di apertura dei coni.
sterad_v2 = zeros (80, 120, 79);
% matrice che contiene l'angolo solido corrispondente ad ogni punto.
lux_v2 = zeros (80, 120, 79);
% matrice in cui salverò i valori in lux di illuminazione.
for i = 1:80 for j = 1:120 for z = 2:80
% Calcolo volume piramidale.
vol_pir_v1(i, j, z) = 4 * distanza1(i, j, z) / 3;
vol_pir_v2(i, j, z) = 4 * distanza2(i, j, z) / 3;
% Per il calcolo del volume conico considero un raggio di base
% di 1.4 mm (radice di 2).
vol_con_v1 (i, j, z) = pi * 2 * distanza1(i, j, z) / 3;
vol_con_v2 (i, j, z) = pi * 2 * distanza2(i, j, z) / 3;
% Calcolo approssimazione commessa.
appros_v1 (i, j, z) = vol_pir_v1(i, j, z) / vol_con_v1 (i, j, z);
appros_v2 (i, j, z) = vol_pir_v2(i, j, z) / vol_con_v2 (i, j, z);
% Calcolo dell'angolo di apertura del cono corrispondente ad ogni punto.
ang_ap_v1(i, j, z) = 2 * atan ( sqrt(2) / distanza1 (i, j, z));
ang_ap_v2(i, j, z) = 2 * atan ( sqrt(2) / distanza2 (i, j, z));
% Calcolo angolo solido corrispondente ad ogni punto.
sterad_v1 (i, j, z) = 2 * pi * (1 - cos ( ang_ap_v1(i, j, z) / 2));
sterad_v2 (i, j, z) = 2 * pi * (1 - cos ( ang_ap_v2(i, j, z) / 2));
% Calcolo matrice con illuminazione in lux. Occorre in questo
% caso convertire le millicandele in candele (dividendo per
% 1000), e la superdicie in m2 (dividendo per 0,000001).
lux_v1 (i, j, z) = space(i, j, z) * sterad_v1 (i, j, z) * 1000 / 4;
lux_v2 (i, j, z) = space(i, j, z) * sterad_v2 (i, j, z) * 1000 / 4;
end
end end
% Visualizzazione dei risultati ottenuti
for k = 1:N
% Costruisco le matrici che contengono solo il campo di vista
171
% delle due videocamere.
oriz = round (dim_oriz(k)/2);
vert = round (dim_vert(k)/2);
if ( mod(oriz, 2) == 0 ) % se è pari oriz = oriz + 1;
end
if ( mod(vert, 2) == 0 ) % se è pari vert = vert + 1;
end
% Ricavo la mappa della percentuale di approssimazione fatta
% modificando la forma del volume da piramidale a conica
FOV_appross_v1 = appros_v1 ((40 - fix(vert/2)):(40 + fix(vert/2)), (54 - fix(oriz/2)):(54 + fix(oriz/2)), dist_vis(k)/2);
FOV_appross_v2 = appros_v2 ((40 - fix(vert/2)):(40 + fix(vert/2)), (60 - fix(oriz/2)):(60 + fix(oriz/2)), dist_vis(k)/2);
% Ricavo il valore di illuminazione in lux per le due videocamere FOV_lux_v1 = lux_v1 ((40 - fix(vert/2)):(40 + fix(vert/2)), (54 - fix(oriz/2)):(54 + fix(oriz/2)), dist_vis(k)/2);
FOV_lux_v2 = lux_v2 ((40 - fix(vert/2)):(40 + fix(vert/2)), (60 - fix(oriz/2)):(60 + fix(oriz/2)), dist_vis(k)/2);
% Ricerca valori puntuali inferiori al valore minimo imposto dalla
% videocamera.
[I1 J1] = find (FOV_lux_v1 <= 1.5);
% verifica che tali errori siano nulli if (isempty (I1))
display (['Nessun errore sulla videocamera 1 a distanza 'num2str(dist_vis(k))]);
end
[I2 J2] = find (FOV_lux_v2 <= 1.5);
if (isempty (I1))
display (['Nessun errore sulla videocamera 2 a distanza 'num2str(dist_vis(k))]);
end
% Visualizzo i valori di approssimazione fatti.
figure, subplot(1, 2, 1), imagesc (((54 - fix(oriz/2)):(54 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_appross_v1),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Valore di approssimazione'),...
title(['Valore di approssimazione prima videocamera alla distanza ' num2str(dist_vis(k)) ' mm']),...
colorbar('EastOutside');
subplot(1, 2, 2), imagesc (((60 - fix(oriz/2)):(60 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_appross_v2),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Valore di approssimazione'),...
title(['Valore di approssimazione seconda videocamera alla distanza ' num2str(dist_vis(k)) ' mm']),...
colorbar('EastOutside');
% Visualizzo i valori di illuminazione in lux.
figure, subplot(1, 2, 1), mesh (((54 - fix(oriz/2)):(54 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_lux_v1),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Illuminazione (lux)'),...
title(['Valore di illuminazione prima videocamera alla distanza ' num2str(dist_vis(k)) ' mm']);
172
subplot(1, 2, 2), mesh (((60 - fix(oriz/2)):(60 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_lux_v2),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Illuminazione (lux)'),...
title(['Valore di illuminazione seconda videocamera alla distanza ' num2str(dist_vis(k)) ' mm']);
end
% Analisi della dinamica del sensore di visione sfruttata con questa
% configurazione di illuminazione.
% Come nel caso precedente si estrapolano i valori di illuminazione in lux
% e si fa il rapporto tra il valore massimo ottenuto ai vari piani di
% profondità e il valore minimo dichiarato dal costruttore.
dinamica_v1 = zeros(1,N);
% matrice di appoggio per i valori di dinamica della prima videocamera dinamica_v2 = zeros(1,N);
% matrice di appoggio per i valori di dinamica della seconda videocamera Max1 = zeros (1,N);
% vettore di appoggio per i valori massimi di intensità per la prima videocamera Max2 = zeros (1,N);
% vettore di appoggio per i valori massimi di intensità per la seconda videocamera
for f = 1:N
% Costruisco le matrici che contengono solo il campo di vista delle due videocamere.
oriz = round (dim_oriz(f)/2);
vert = round (dim_vert(f)/2);
if ( mod(oriz, 2) == 0 ) % se è pari oriz = oriz + 1;
end
if ( mod(vert, 2) == 0 ) % se è pari vert = vert + 1;
end
% Ricavo il valore di illuminazione in lux per le due videocamere FOV_lux_v1 = lux_v1 ((40 - fix(vert/2)):(40 + fix(vert/2)), (54 - fix(oriz/2)):(54 + fix(oriz/2)), dist_vis(f)/2);
FOV_lux_v2 = lux_v2 ((40 - fix(vert/2)):(40 + fix(vert/2)), (60 - fix(oriz/2)):(60 + fix(oriz/2)), dist_vis(f)/2);
% Calcolo il valore massimo di illuminazione in lux per le due videocamere M1 = max(FOV_lux_v1);
Max1 (f) = max(M1);
M2 = max(FOV_lux_v2);
Max2 (f) = max(M2);
% Calcolo il valore della dinamica sfruttata dinamica_v1(f) = 20 * log10 (Max1 (f)/1.5);
dinamica_v2(f) = 20 * log10 (Max2 (f)/1.5);
end
% Visualizzo i valori di dinamica sfruttata alle varie profondità
figure, plot (dist_vis(1), dinamica_v1 (1), '.r', dist_vis(2), dinamica_v1 (2), '.r', dist_vis(3), dinamica_v1 (3), '.r',...
dist_vis(4), dinamica_v1 (4), '.r', dist_vis(5), dinamica_v1 (5), '.r', dist_vis(6), dinamica_v1 (6), '.r',...
173
dist_vis(7), dinamica_v1 (7), '.r', dist_vis(8), dinamica_v1 (8), '.r', dist_vis(9), dinamica_v1 (9), '.r',...
dist_vis(10), dinamica_v1 (10), '.r'),...
title('Andamento della dinamica sfruttata per la prima videocamera'),...
xlabel('Profondità (mm)'), ylabel('Dinamica (dB)');
figure, plot (dist_vis(1), dinamica_v2 (1), '.r', dist_vis(2), dinamica_v2 (2), '.r', dist_vis(3), dinamica_v2 (3), '.r',...
dist_vis(4), dinamica_v2 (4), '.r', dist_vis(5), dinamica_v2 (5), '.r', dist_vis(6), dinamica_v2 (6), '.r',...
dist_vis(7), dinamica_v2 (7), '.r', dist_vis(8), dinamica_v2 (8), '.r', dist_vis(9), dinamica_v2 (9), '.r',...
dist_vis(10), dinamica_v2 (10), '.r'),...
title('Andamento della dinamica sfruttata per la seconda videocamera'),...
xlabel('Profondità (mm)'), ylabel('Dinamica (dB)');
% Visualizzo gli andamenti dei valori massimi
figure, plot (dist_vis(1), Max1 (1), '.r', dist_vis(2), Max1 (2), '.r', dist_vis(3), Max1 (3), '.r',...
dist_vis(4), Max1 (4), '.r', dist_vis(5), Max1 (5), '.r', dist_vis(6), Max1 (6), '.r',...
dist_vis(7), Max1 (7), '.r', dist_vis(8), Max1 (8), '.r', dist_vis(9), Max1 (9), '.r',...
dist_vis(10), Max1 (10), '.r'),...
title('Andamento del massimo valore di intensità luminosa per la prima videocamera'),...
xlabel('Profondità (mm)'), ylabel('Intensità Luminosa (lux)');
figure, plot (dist_vis(1), Max2 (1), '.r', dist_vis(2), Max2 (2), '.r', dist_vis(3), Max2 (3), '.r',...
dist_vis(4), Max2 (4), '.r', dist_vis(5), Max2 (5), '.r', dist_vis(6), Max2 (6), '.r',...
dist_vis(7), Max2 (7), '.r', dist_vis(8), Max2 (8), '.r', dist_vis(9), Max2 (9), '.r',...
dist_vis(10), Max2 (10), '.r'),...
title('Andamento del massimo valore di intensità luminosa per la seconda videocamera'),...
xlabel('Profondità (mm)'), ylabel('Intensità Luminosa (lux)');
2) Modello a sei LED in configurazione esagonale
%%% SECONDA PROVA: analisi del sistema di illuminazione composto da 6 LED.
%%% Viene considerata la direttività funzionale del LED. Inoltre è
%%% utilizzata la configurazione a 6 LED esagonale.
close all clear all
% Inizializzo una matrice tridimensionale che sarà il mio spazio di lavoro
% in cui ogni cella della matrice equivale ad un cubo di 2 mm di lato space = zeros (80, 120, 80);
% Inizializzo i parametri del LED e nel mezzo di propagazione (acqua)
% Ipotizzo una attenuazione esponenziale, che il mezzo sia omogeneo e si
% tratti solo di aqua. Non considero nè riflessioni, nè rifrazioni nè
% scattering, ma solo l'assorbimento del mezzo
I0 = 1000; % Intensità emessa dal LED misurata in millicandele (mcd) coeff_abs = -0.00001;
% coefficiente assorbimento dell'anidride carbonica. Tale valore corrisponde ad una approssimazione in quanto lo spettro di emissione del LED è stato
approssimato alla sola componente maggioritaria e quindi tale coefficiente di
% assorbimento equivale alla sola lunghezza d'onda di 600 mm.
174
% Parametri della funzione sigmoide di emissione stimata precedentemente.
% Tale funziona approssima la direttività di emissione luminosa del LED
% utilizzato.
a_par = -2.9;
b_par = 1.3;
c_par = 1.1;
d_par = -0.25;
% Inizializzo la posizione dei LED: visti come sorgenti puntuali di luce,
% con un proprio angolo verticale e orizzontale di irraggiamento e con una
% emissione continua a intensità costante (calcolata come valore medio nel datasheet).
% Da notare che le posizioni delle due videocamere adesso sono (40,54,1) e
% (40,60,1). (ho imposto una distanza tra le due aperture delle videocamere
% di 5 celle, cioè dispari, per avere una cella centrale alla quale
% riferire il fov stereoscopico).
X = [55 59 63 59 55 51];
Y = [43 43 40 37 37 40];
Z = [1 1 1 1 1 1];
% Analisi dell'Intensità. Come ipotesi di lavoro considero che le intensità
% in ogni punto derivanti dai diversi LED si sommino, quindi è trascurata
% la natura ondulatoria della luce che avrebbe costretto ad una analisi di
% interferenza delle singole onde luminose generate.
for h = 1:6
space (Y(h), X(h), Z(h)) = I0;
for i = 1:80 for j = 1:120 for z = 2:80
% Calcolo gli angoli tra punto considerato e emettitore alfa = atan ( (j - X(h)) / (z - Z(h)) );
theta = atan ( (i - Y(h)) / (z - Z(h)) );
% Rendo i due angoli positivi per poi poter utilizzare la funzione sigmf.
if (alfa < 0)
alfa = alfa * (-1);
end
if (theta < 0)
theta = theta * (-1);
end
% Calcolo il valore dell'intensità in funzione dell'angolo orizzontale e verticale secondo una funzione sigmoide ricavata dal datasheet
distanza1 = (2*i - 2*Y(h))^2 + (2*j - 2*X(h))^2 + (2*z - 2*Z(h))^2;
distanza = sqrt (distanza1);
space (i, j, z) = space (i, j, z) + I0 * exp (coeff_abs * distanza)*...
( b_par * sigmf (theta, [a_par c_par]) + d_par ) * ( b_par * sigmf (alfa, [a_par c_par] + d_par) );
end end end end
% Visualizzazione dei Risultati.
% Viene visualizzato l'andamento dell'intensità luminosa all'interno del
% campo di vista stereoscopico.
% Dal datasheet delle telecamere è possibile individuare, con una lunghezza
% focale di 3.1 mm, ovvero quella che comunemnete utilizzo, un angolo di
% apertura orizzontale di 65° 39' = 65,65° (1.148875 rad)e un angolo di
175
% apertura verticale di 52° 50' = 52.835° (0.9246125 rad). Le videocamera
% sono in posizione (40,57,1) e (40,63,1) secondo la configurazione dei
% LED schelta. Il FOV stereoscopico è dato da un'apertura di 65,59° e con
% shift in profondità di 6.75 mm (vedi calcoli quaderno). Tale
% FOV è centrato quindi nel punto di mezzo tra le due videocamere.
dist_vis = [20 30 40 50 70 80 100 110 130 150];
% vettore con le profondità che voglio visualizzare N = length(dist_vis);
Campo_visivo = zeros(80, 120, N);
dim_oriz = zeros (1,N);
% vettore per salvare le dimensioni reali del FOV dim_vert = zeros (1,N);
% vettore per salvare le dimensioni reali del FOV oriz_ster = zeros (1,N);
% vettore di appoggio per salvare le dimensioni del FOV stereoscopico vert_ster = zeros (1,N);
% vettore di appoggio per salvare le dimensioni del FOV stereoscopico oriz_st = zeros (1, N);
% vettore di appoggio per salvare la dimensione orizzontale del FOV della
% videocamera alle varie profondità.
vert_st = zeros (1, N);
% vettore di appoggio per salvare la dimensione verticale del FOV della
% videocamera alle varie profondità.
for u = 1:N
% calcolo le dimensioni effettive, orizzontali e verticali, del campo di
% vista di ogni videocamera, a quella data distanza dim_oriz(u) = 2*dist_vis(u)*tan(1.148875/2);
dim_vert(u) = 2*dist_vis(u)*tan(0.9246125/2);
% Calcolo la dimensione del FOV stereoscopico a questa stessa profondità.
oriz_ster(u) = 2 * (dist_vis(u) - 6.75) * tan(1.148875/2);
vert_ster(u) = 2 * (dist_vis(u) - 6.75) * tan(0.9246125/2);
% Eseguo le stesse operazioni di approssimazione eseguite anche precedentemente.
oriz_st(u) = round (oriz_ster(u)/2);
vert_st(u) = round (vert_ster(u)/2);
if ( mod(oriz_st(u), 2) == 0 ) % se è pari oriz_st(u) = oriz_st(u) +1;
end
if ( mod(vert_st(u), 2) == 0 ) % se è pari vert_st(u) = vert_st(u) +1;
end
% Costruisco una matrice che ha 1 in corrispondenza del campo di vista
% stereoscopico alla profondità data. Ricordare che l'origine del campo
% di vista stereoscopico è in posizione (40,57,1). Gli estremi sono stati resi dispari in modo da centrarli e quindi occorre approssimarli con la funzione fix
% ad un intero.
H_FOV = space ( (40 - fix(vert_st(u) /2)):(40 + fix(vert_st(u) /2)), (57 - fix(oriz_st(u) /2)):(57 + fix(oriz_st(u) /2)) );
% Per poter visualizzare contemporaneamente il campo visivo stereoscopico e
% l'andamento dell'intensità luminosa ad uno stesso piano di profondità
% è però necessario andare a calcolare il valore massimo di intensità a
% tale profondità e fornire tale valore (leggermente incrementato) al
176
% grafico del campo visivo per fare in modo che "emerga" dal secondo
% grafico.
MAX = max(space (:,:, dist_vis(u)/2));
M = max (MAX);
% Vado poi a costruire la matrice con il Campo Visivo stereoscopico;
% che sarà centrato sulla cella corrispondente alla telecamera (40, 57) Campo_visivo ( (40 + fix(vert_st(u)/2)), (57 - fix(oriz_st(u)/2)):(57 + fix(oriz_st(u)/2)), u ) = M + 50;
Campo_visivo ( (40 - fix(vert_st(u)/2)), (57 - fix(oriz_st(u)/2)):(57 + fix(oriz_st(u)/2)), u ) = M + 50;
Campo_visivo ( (40 - fix(vert_st(u)/2)): (40 + fix(vert_st(u)/2)), (57 + fix(oriz_st(u)/2)), u ) = M + 50;
Campo_visivo ( (40 - fix(vert_st(u)/2)): (40 + fix(vert_st(u)/2)), (57 - fix(oriz_st(u)/2)), u ) = M + 50;
% Visualizzo i risultati ottenuti: a sinistra è mostrato il campo di
% vista stereoscopico, mentre a destra l'andamento dell'intensità
% luminosa con sovrapposto il campo di vista stereoscopico
figure, subplot(1, 2, 1), imagesc(Campo_visivo(:, :, u)), title (['Campo visivo stereoscopico alla profondità di ' num2str(dist_vis(u)) ' mm']);
subplot(1, 2, 2), mesh(space (:,:, dist_vis(u)/2)), hold on, mesh(Campo_visivo (:, :, u)),...
xlabel('distanza (mm)'), ylabel('distanza (mm)'), zlabel('Intensità Luminosa (mcd)'),...
title(['Andamento di intensità luminosa alla profontià di ' num2str(dist_vis(u)) ' mm con sovrapposto il campo visivo stereoscopico']);
% Visualizzo l'andamento dell'intensità luminosa nel solo campo di vista stereoscopico
figure,...
mesh((57 - oriz_st(u)/2):(57 + oriz_st(u)/2), (40 - vert_st(u)/2):(40 + vert_st(u)/2), space((40 - vert_st(u)/2):(40 + vert_st(u)/2), (57 - oriz_st(u)/2):(57 + oriz_st(u)/2), dist_vis(u)/2)),...
title (['Andamento intensità interno al campo di vista stereoscopico alla profondità di ' num2str(dist_vis(u)) ' mm']),...
zlabel('intensità in mcd'), xlabel('distanza orizzontale in 2mm'), ylabel('distanza verticale in 2mm');
end
% Analisi dell'uniformità dell'illuminazione: calcolo del numero di punti all'interno del campo di vista stereoscopico con Coefficiente di Variazione inferiore al 5% Il coefficiente di variazione è definito come il rapporto tra la
% deviazione dalla media del valore puntuale e la media dei valori di luminosità.
CV = zeros(1,N);
% Vettore di appoggio sul quale salverò i valori del numero di punti con coefficiente di variazione inferiore al 5% per ogni valore di profondità
mean = zeros (1,N);
% Vettore di appoggio nel quale salverò il valore medio di intensità
% luminosa al variare della profondità.
for u = 1 : N
profondita = dist_vis (u);
% Carico i valori della dimensione del campo di vista stereoscopico
% alla profondità corrente oriz = oriz_st (u);
vert = vert_st (u);
% La matrice che corrisponde ai valori di intensità luminosa
177
% all'interno del campo di vista stereoscopico è dunque ricavabile
% grazie agli estremi ricavati. Tali estremi sono stati resi dispari in
% modo da centrarli e quindi occorre approssimarli con la funzione fix
% ad un intero.
H = space((40 - fix(vert/2)):(40 + fix(vert/2)), (57 - fix(oriz/2)):(57 + fix(oriz/2)), dist_vis(u)/2);
% Calcolo il valore medio dell'intensità luminosa all'interno del campo
% di vista appena costruito [L K] = size (H);
S = sum (H);
St = sum (S);
mean(u) = St / (L * K);
H1 = zeros (L, K); % matrice di appoggio per i valori di CV CV_image = zeros (L,K); % matrice di appoggio per la visualizzasione int = 0; % contatore del numero di punti con CV ottimale
for i = 1 : L for j = 1 : K
H1 (i, j) = (H(i, j) - mean(u)) / mean(u);
end end
% Conteggio e visualizzazione dei punti del FOV con CV < 5%
for i = 1 : L for j = 1 : K
if ( (H1(i,j) >= -0.05)&& (H1(i,j) <= 0.05)) CV_image(i,j) = H1 (i,j);
int = int + 1;
end end end
CV(u) = int / (L * K);
% Visualizzazione delle mappe del Coefficiente di Variazione inferiore a 5% nel FOV stereoscopico
figure, imagesc(CV_image), title(['Punti del FOV con CV inferiore al 5% alla distanza di ' num2str(dist_vis(u)) ' mm']),colorbar('EastOutside');
figure, surf(H), colormap('jet'), shading('interp'),...
xlabel('distanza (mm)'), ylabel('distanza (mm)'), zlabel('Intensità Luminosa (mcd)'),...
title(['Intensità luce nel campo di vista stereoscopico alla distanza di ' num2str(dist_vis(u)) ' mm']),...
colorbar('EastOutside');
end
% Visualizzo l'andamento con la profondità del numero di punti con CV < 5%
figure, plot (dist_vis(1), CV (1), '.r',dist_vis(2), CV (2), '.r', dist_vis(3), CV (3), '.r',...
dist_vis(4), CV (4), '.r', dist_vis(5), CV (5), '.r', dist_vis(6), CV (6), '.r',...
dist_vis(7), CV (7), '.r', dist_vis(8), CV (8), '.r', dist_vis(9), CV (9), '.r',...
dist_vis(10), CV (10), '.r'),...
title('Andamento della Percentuale del FOV che ha CV minore del 5%'),...
xlabel('Profondità (mm)'), ylabel('Percentuale FOV');
% Visualizzo l'andamento della media intensità luminosa
178
figure, plot (dist_vis(1), mean (1), '.r', dist_vis(2), mean (2), '.r', dist_vis(3), mean (3), '.r',...
dist_vis(4), mean (4), '.r', dist_vis(5), mean (5), '.r', dist_vis(6), mean (6), '.r',...
dist_vis(7), mean (7), '.r', dist_vis(8), mean (8), '.r', dist_vis(9), mean (9), '.r',...
dist_vis(10), mean (10), '.r'),...
title('Andamento intensità luminosa media nel campo di vista stereoscopico'),...
xlabel('Profondità (mm)'), ylabel('Intensità Luminosa (mcd)');
% Analisi uniformità dell'illuminazione. Viene calcolata la deviazione
% standard della distribuzione della luce. Di fatto si approssima difatti
% la distribuzione della luce ad una gaussiana.
std_oriz = zeros(1, N);
% vettore di appoggio sul quale memorizzerò i valori di deviazione
% standard orizzontale ottenuti con il modello std_vert = zeros(1, N);
% vettore di appoggio sul quale memorizzerò i valori di deviazione
% standard verticale ottenuti con il modello
for y = 1:N
% Costruisco la matrice che rappresenta la distribuzione dell'intensità
% luminosa nel campo di vista della videocamera. Le dimensioni del FOV
% le ricavo dai vettori precedentemente generati.
oriz = oriz_st(y);
vert = vert_st(y);
H = space((40 - fix(vert/2)):(40 + fix(vert/2)), (57 - fix(oriz/2)):(57 + fix(oriz/2)), dist_vis(y)/2);
% Estraggo due vettori corrispondenti alla riga e alla colonna centrale
% di tale matrice (e quindi del campo di vista).
o = fix (oriz/2) + 1; % fix approssima all'intero inferiore v = fix (vert/2) + 1;
distr_oriz = H(v,:);
distr_vert = H(:,o);
% Visualizzo le distribuzioni orizzontali e verticali
figure, subplot(1, 2, 1), plot (distr_oriz, 'r'), ylabel('Intensità luminosa (mcd)'),...
title ([ 'Distribuzione orizzontale a ' num2str(dist_vis(y)) ' mm' ]);
subplot(1, 2, 2), plot (distr_vert, 'b'), ylabel('Intensità luminosa (mcd)'),...
title ([ 'Distribuzione verticale a ' num2str(dist_vis(y)) ' mm' ]);
% Calcolo del valore medio per normalizzare il valore delle deviazioni
% standard.
mean_oriz = sum(distr_oriz);
mean_oriz = mean_oriz / length(distr_oriz);
mean_vert = sum(distr_vert);
mean_vert = mean_vert / length(distr_vert);
% Calcolo i valori di deviaizone standard e li memorizzo std_oriz (y) = std (distr_oriz) / mean_oriz;
std_vert (y) = std (distr_vert) / mean_vert;
end
% Visualizzo l'andamento delle due deviazioni standard ricavate
figure, plot (dist_vis(1), std_oriz (1), '.r',dist_vis(2), std_oriz (2), '.r', dist_vis(3), std_oriz (3), '.r',...
179
dist_vis(4), std_oriz (4), '.r', dist_vis(5), std_oriz (5), '.r', dist_vis(6), std_oriz (6), '.r',...
dist_vis(7), std_oriz (7), '.r', dist_vis(8), std_oriz (8), '.r', dist_vis(9), std_oriz (9), '.r',...
dist_vis(10), std_oriz (10), '.r'),...
title('Andamento della deviazione standard normalizzata orizzontale'),...
xlabel('Profondità (mm)'), ylabel('Deviazione standard normalizzata');
figure, plot (dist_vis(1), std_vert (1), '.r',dist_vis(2), std_vert (2), '.r', dist_vis(3), std_vert (3), '.r',...
dist_vis(4), std_vert (4), '.r', dist_vis(5), std_vert (5), '.r', dist_vis(6), std_vert (6), '.r',...
dist_vis(7), std_vert (7), '.r', dist_vis(8), std_vert (8), '.r', dist_vis(9), std_vert (9), '.r',...
dist_vis(10), std_vert (10), '.r'),...
title('Andamento della deviazione standard normalizzata verticale'),...
xlabel('Profondità (mm)'), ylabel('Deviazione standard normalizzata');
% Analisi dell'intensità minima di illuminazione ottenuta. In questo caso
% si considera che, da datasheet, le videocamere richiedono una
% illuminazione minima di 1,5 lux. Purtroppo il nostro modello è in mcd e
% quindi occorre prima convertirlo. Tale analisi viene fatta sul campo di
% vista di ogni videocamera singola, solamente alla fine viene verificato
% il superamento del valore minimo all'interno del campo di vista
% stereoscopico.
% costruisco due matrici di appoggio con le distanze di ogni punto dello
% spazio dalle due videocamere singolarmente.
distanza1 = zeros (80, 120, 79); % matrice distanze dalla prima videocamera distanza2 = zeros (80, 120, 79); % matrice distanze dalla seconda videocamera
% Calcolo distanze for i = 1:80
for j = 1:120 for z = 2:80
% Calcolo distanza dalla prima videocamera (posizione 40, 55).
distanz = (2*i - 2*40)^2 + (2*j - 2*55)^2 + (2*z - 2*1)^2;
distanza1(i, j, z) = sqrt(distanz);
% Calcolo distanza dalla seconda videocamera (posizione 40, 60).
distanz = (2*i - 2*40)^2 + (2*j - 2*60)^2 + (2*z - 2*1)^2;
distanza2(i, j, z) = sqrt(distanz);
end
end end
% Per convertire le candele in lux occorre calcolare l'angolo steradiante
% corrispondente ad ogni punto. Si sfrutta quindi il fatto che ogni cella
% ha un'area fissa pari a 4 mm2.
% L'angolo steradiante viene però calcolato facilmente solo per un cono
% mentre in questo caso la figura solida generata sarebbe quella di una
% piramide a base quadrata. Per calcolare l'approssimazione effettuata si
% calcolano i due volumi e se ne fa il rapporto.
% Matrici di appoggio per la prima videocamera vol_pir_v1 = zeros (80, 120, 79);
% matrice in cui salverò i volumi piramidali corrispondenti.
180
vol_con_v1 = zeros (80, 120, 79);
% matrice in cui salverò i volumi conici corrispondenti.
appros_v1 = zeros (80, 120, 79);
% matrice di appoggio approssimazioni.
ang_ap_v1 = zeros (80, 120, 79);
% matrice con i corrispondenti angoli di apertura dei coni.
sterad_v1 = zeros (80, 120, 79);
% matrice che contiene l'angolo solido corrispondente ad ogni punto.
lux_v1 = zeros (80, 120, 79);
% matrice in cui salverò i valori in lux di illuminazione.
% Matrici di appoggio per la seconda videocamera vol_pir_v2 = zeros (80, 120, 79);
% matrice in cui salverò i volumi piramidali corrispondenti.
vol_con_v2 = zeros (80, 120, 79);
% matrice in cui salverò i volumi conici corrispondenti.
appros_v2 = zeros (80, 120, 79);
% matrice di appoggio approssimazioni.
ang_ap_v2 = zeros (80, 120, 79);
% matrice con i corrispondenti angoli di apertura dei coni.
sterad_v2 = zeros (80, 120, 79);
% matrice che contiene l'angolo solido corrispondente ad ogni punto.
lux_v2 = zeros (80, 120, 79);
% matrice in cui salverò i valori in lux di illuminazione.
for i = 1:80 for j = 1:120 for z = 2:80
% Calcolo volume piramidale.
vol_pir_v1(i, j, z) = 4 * distanza1(i, j, z) / 3;
vol_pir_v2(i, j, z) = 4 * distanza2(i, j, z) / 3;
% Per il calcolo del volume conico considero un raggio di base di 1.4 mm (radice di 2).
vol_con_v1 (i, j, z) = pi * 2 * distanza1(i, j, z) / 3;
vol_con_v2 (i, j, z) = pi * 2 * distanza2(i, j, z) / 3;
% Calcolo approssimazione commessa.
appros_v1 (i, j, z) = vol_pir_v1(i, j, z) / vol_con_v1 (i, j, z);
appros_v2 (i, j, z) = vol_pir_v2(i, j, z) / vol_con_v2 (i, j, z);
% Calcolo dell'angolo di apertura del cono corrispondente ad ogni punto.
ang_ap_v1(i, j, z) = 2 * atan ( sqrt(2) / distanza1 (i, j, z));
ang_ap_v2(i, j, z) = 2 * atan ( sqrt(2) / distanza2 (i, j, z));
% Calcolo angolo solido corrispondente ad ogni punto.
sterad_v1 (i, j, z) = 2 * pi * (1 - cos ( ang_ap_v1(i, j, z) / 2));
sterad_v2 (i, j, z) = 2 * pi * (1 - cos ( ang_ap_v2(i, j, z) / 2));
% Calcolo matrice con illuminazione in lux. Occorre in questo caso convertire le millicandele in candele (dividendo per 1000), e la superficie in m2 (dividendo per 0,000001).
lux_v1 (i, j, z) = space(i, j, z) * sterad_v1 (i, j, z) * 1000 / 4;
lux_v2 (i, j, z) = space(i, j, z) * sterad_v2 (i, j, z) * 1000 / 4;
end
end end
% Visualizzazione dei risultati ottenuti.
181
for k = 1:N
% Costruisco le matrici che contengono solo il campo di vista delle due videocamere.
oriz = round (dim_oriz(k)/2);
vert = round (dim_vert(k)/2);
if ( mod(oriz, 2) == 0 ) % se è pari oriz = oriz + 1;
end
if ( mod(vert, 2) == 0 ) % se è pari vert = vert + 1;
end
% Ricavo la mappa della percentuale di approssimazione fatta modificando la forma del volume da piramidale a conica
FOV_appross_v1 = appros_v1 ((40 - fix(vert/2)):(40 + fix(vert/2)), (55 - fix(oriz/2)):(55 + fix(oriz/2)), dist_vis(k)/2);
FOV_appross_v2 = appros_v2 ((40 - fix(vert/2)):(40 + fix(vert/2)), (60 - fix(oriz/2)):(60 + fix(oriz/2)), dist_vis(k)/2);
% Ricavo il valore di illuminazione in lux per le due videocamere FOV_lux_v1 = lux_v1 ((40 - fix(vert/2)):(40 + fix(vert/2)), (55 - fix(oriz/2)):(55 + fix(oriz/2)), dist_vis(k)/2);
FOV_lux_v2 = lux_v2 ((40 - fix(vert/2)):(40 + fix(vert/2)), (60 - fix(oriz/2)):(60 + fix(oriz/2)), dist_vis(k)/2);
% Ricerca valori puntuali inferiori al valore minimo imposto dalla videocamera.
[I1 J1] = find (FOV_lux_v1 <= 1.5);
% verifica che tali errori siano nulli if (isempty (I1))
display (['Nessun errore sulla videocamera 1 a distanza 'num2str(dist_vis(k))]);
end
[I2 J2] = find (FOV_lux_v2 <= 1.5);
if (isempty (I1))
display (['Nessun errore sulla videocamera 2 a distanza 'num2str(dist_vis(k))]);
end
% Visualizzo i valori di approssimazione fatti.
figure, subplot(1, 2, 1), imagesc (((54 - fix(oriz/2)):(54 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_appross_v1),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Valore di approssimazione'),...
title(['Valore di approssimazione prima videocamera alla distanza ' num2str(dist_vis(k)) ' mm']),...
colorbar('EastOutside');
subplot(1, 2, 2), imagesc (((60 - fix(oriz/2)):(60 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_appross_v2),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Valore di approssimazione'),...
title(['Valore di approssimazione seconda videocamera alla distanza ' num2str(dist_vis(k)) ' mm']),...
colorbar('EastOutside');
% Visualizzo i valori di illuminazione in lux.
figure, subplot(1, 2, 1), mesh (((54 - fix(oriz/2)):(54 + fix(oriz/2))), ((40 - fix(vert/2)):(40 + fix(vert/2))), FOV_lux_v1),...
ylabel('distanza (2mm)'), xlabel('distanza (2mm)'), zlabel('Illuminazione (lux)'),...
title(['Valore di illuminazione prima videocamera alla distanza ' num2str(dist_vis(k)) ' mm']);