APPENDICE
MATERIALE AGGIUNTIVO
Nella presente appendice vengono mostrati alcuni esempi di codice C, Matlab e VHDL realizzati durante il lavoro di tesi.
Per motivi di spazio si è preferito evitare di riportare tutti gli elaborati utilizzati nei tre ambienti citati sopra. Per la visione completa dei codici si rimanda pertanto al CD-ROM allegato alla tesi, contenente la versione definitiva e completa dei codici ret_soft.c e della sua versione semplificata ret_soft_linear.c, tutti gli altri programmi C e Matlab utilizzati ed infine il codice completo VHDL, utilizzato per la simulazione funzionale e come ingresso per il tool di sintesi Xilinx ISE 6.
CODICE C
Per l’ambiente C si riporta parte del codice dell’algoritmo semplificato ret_soft_linear.c, come modellizzazione della descrizione VHDL e la funzione cutfloat per il troncamento della parte frazionaria a 10 bit per un float in ingresso.
/* --- Troncamento frazionaria a 10 bit ---*/
float cutfloat(in){
float in;
float out;
out=(float)floor (in * 1024) / 1024;
return (out);
}
/* --- Parte del codice ret_soft_linear.c ---*/
main() {
[...]
* Inizio cicli di filtraggio */
if (tr>=1) {
printf ("Ciclo 1 \n");
for (i=1; i<=dimx-2; i++) { for (j=1; j<=dimy-2; j++) {
fo=y[i-1][j]*(coeff_b)+y[i][j]*(1-coeff_b);
fv=y[i][j-1]*(coeff_b)+y[i][j]*(1-coeff_b);
/* limito a 3 le cifre decimali di fo ed fv */
focut=cutfloat(fo);
fvcut=cutfloat(fv);
/* legge LUT */
so=mo[i][j];
sv=mv[i][j];
/* limito a 3 le cifre decimali do So ed Sv */
socut=cutfloat(so);
svcut=cutfloat(sv);
/* leggo rom per calcolo di inverso di so+sv+1 */
z= socut+svcut+1;
zint= (int)z;
zdec= (int)(z*10) - zint * 10;
/* calcolo indirizzo per rom inversione */
if ( z >= 50 ) if (z==2001 )
index = 2440;
else
index = zint + 440;
else
index = ((zint * 10)-10+zdec);
invdencut = invdenromcut[index];
/* calcolo addendi del numeratore di y(i,j) limitando ogni volta a 3 le cifre decimali */
sofo=socut*focut;
sofocut=cutfloat(sofo);
svfv=svcut*fvcut;
svfvcut=cutfloat(svfv);
ycut[i][j]=cutfloat(y[i][j]);
/* calcolo y(i,j) come prodotto, shifto risultato e ne limito la parte decimale a 3 cifre */
y[i][j]=((sofocut+svfvcut+ycut[i][j])* invdencut) / 4096;
ycut[i][j]=cutfloat(y[i][j]);
y[i][j]=ycut[i][j];
/* saturo eventuali valori errati di y a 255 per non avere overflow sugli 8 bit della parte intera che consentono di arrivare a 255 */
if (y[i][j] >= 256) y[i][j] = 255;
} }}
CODICE MATLAB
In questa sezione si riportano i codici delle funzioni save_image_txt.m, save_image_img.m, psnr.m. La funzione save_ref_img.m non viene riportata in
quanto differente da save_image_img.m solo per il numero di bit nella conversione da binario a decimale.
function save_image(image_in,nomefile_out)
% salva una matrice in formato .txt .
% nome: nome del file
% image: nome della matrice
img=load_image(image_in);
fid = fopen (nomefile_out,'w');
[dimx,dimy]=size(img);
for j=1:1:dimy for i=1:1:dimx a= img(i,j);
b=bin(a,8);
for k=1:1:8 b(k);
fprintf(fid, '%d',b(k));
end
fprintf(fid,'\r\n');
end end
fclose(fid);
fprintf('Lunghezza delle righe:') dimx
fprintf('Lunghezza delle colonne:') dimy
function psnr(imm1,imm2,dimy,dimx)
img1=load_image(imm1);
img2=load_image(imm2);
diff=img1-img2;
errquad=0;
for i=1:1:dimy
for j=1:1:dimx
errquad=errquad + diff(i,j).^2;
end end
totcelle=(dimx).*(dimy);
errquadmedio=errquad ./ totcelle;
fprintf('Errore quadratico medio:') errquadmedio
fprintf('Rapporto segnale rumore di picco in dB:') PSNR=(10.*log10((255.^2)./errquadmedio))
function save_image_img(nomefile_in,nomefile_out,dimx,dimy)
% salva una matrice in formato .img a partire dal formato .txt
% nomefile_in: nome del file di testo di ingresso
% nomefile_out: nome del file di uscita .img
filein = fopen (nomefile_in,'r'); % apre un file in lettura
for i=1:1:(dimy) for j=1:1:(dimx)
s=[0 0 0 0 0 0 0 0];
a=0;
for k=1:1:8
s(k)=fscanf (filein,'%1d',[1 1]);
a= a + s(k).* 2.^(8-k);
image(i,j)=a;
end % a end end
fclose(filein);
imaget=image';
save_image(nomefile_out,imaget);
CODICE VHDL
Come esempi di VHDL, vengono riportati parte del top-level del sistema, ossia l’entity retinex_A, un esempio di architettura descritta in modo behavioural, il flip-flop D, e un esempio di architettura descritta in modo structural.
--- -- Top-level del sistema (solo entity) -- ---
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Retinex_A is
generic ( M: integer:= 7;
N: integer:= 9);
port (clk, enable, reset: in std_logic;
start: in std_logic
alfa: in std_logic_vector (1 downto 0);
lines_in,cols_in: in std_logic_vector (9 downto 0);
cycles: in std_logic_vector (1 downto 0);
frame_y_valid: out std_logic;
frame_r_valid: out std_logic);
end Retinex_A;
--- -- Entity alfa_par per la decodifica di alfa -- ---
entity alfa_par is
port (alfa_in : in std_logic_vector (1 downto 0);
alfa_out: out std_logic_vector (9 downto 0));
end alfa_par;
architecture behv of alfa_par is
begin
process (alfa_in) begin
case alfa_in is
when "01" => alfa_out <= "1000000000";
when "10" => alfa_out <= "1100000000";
when "11" => alfa_out <= "1110011001";
when others => alfa_out <= "ZZZZZZZZZZ";
end case;
end process;
end behv;
--- -- Entity memories_addr_gen (genera indirizzi per -- -- le memorie nella fase di start -- ---
entity memories_addr_gen is
generic (C: integer:= 49151);
port ( clk_mag: in std_logic;
reset_mag,reset_en: in std_logic;
enable_mag: in std_logic;
lines,cols: in std_logic_vector(9 downto 0);
stop_mag : out std_logic;
addr_x,addr_y: out std_logic_vector (19 downto 0);
addr_inv: out std_logic_vector (11 downto 0));
end memories_addr_gen;
architecture structure of memories_addr_gen is
component memories_counter
generic (C: integer:= 49151);
port (clk_mc, reset_mc, enable_mc : in std_logic;
in_mc : in integer range 0 to C+1;
out_mc: out std_logic;
count_out: out integer range 0 to C+1 );
end component;
component dff
port (d : in std_logic;
clk : in std_logic;
reset_as : in std_logic;
enable : in std_logic;
q : out std_logic);
end component;
signal endcount,end_inv: std_logic;
signal index_x_y: integer range 0 to C+1;
signal index_inv: integer range 0 to 2441;
signal frame_dim: integer range 0 to C+1;
signal enable_reg1: std_logic;
signal reset: std_logic;
signal vcc: std_logic;
begin
vcc <= '1';
reset <= reset_mag or reset_en;
ff1: dff port map (enable_mag,clk_mag,reset,vcc,enable_reg1);
frame_dim <= (conv_integer(lines)) * (conv_integer(cols)) ;
c_start_x_y: memories_counter port map
(clk_mag,reset,enable_reg1,frame_dim ,endcount,index_x_y);
c_start_inv: memories_counter port map
(clk_mag,reset,enable_reg1,2441,end_inv,index_inv);
stop_mag <= endcount;
addr_x <= conv_std_logic_vector(index_x_y,20);
addr_y <= conv_std_logic_vector(index_x_y,20);
addr_inv <= conv_std_logic_vector(index_inv,12);
end structure;
--- -- Entity Dff -- ---
ENTITY dff is
port( d : in std_logic;
clk : in std_logic;
reset_as : in std_logic;
enable : in std_logic;
q : out std_logic);
END dff;
architecture BEHAVIOURAL of dff is
BEGIN
DFF:process (clk, reset_as) begin
IF (reset_as = '1') THEN q <= '0';
ELSIF (clk'EVENT AND clk='1') THEN
if (enable = '1') then q <= d;
else null; -- se enable = 0 conserva lo stato -- end if;
END IF;
END process DFF;
END BEHAVIOURAL;