📄 chapter11_models.vhd
字号:
-- image processing package declaration
-- (for BEH_INT and BEH_STRUC libraries)
library IEEE;
use ieee.std_logic_1164.all;
---------------- package declaration -----------------------------
package image_processing is
--------declare constants
constant foreground:integer:=255;
constant background:integer:=0;
---------------- declare types and subtypes ----------------------
subtype pixel is integer;
type pix3 is array (1 to 3) of pixel;
type pixel3_3 is array(1 to 3, 1 to 3) of pixel;
subtype filter_out is integer;
subtype direction is bit_vector(2 downto 0);
---------------- declare functions and a procedure ---------------
function weight
( X1,X2,X3: pixel)
return filter_out;
function shift
( A: pix3;
B: pixel)
return pix3;
function horizontal_filter
( A: pixel3_3)
return filter_out;
function vertical_filter
( A: pixel3_3)
return filter_out;
function diagonal_l_filter
( A: pixel3_3)
return filter_out;
function diagonal_r_filter
( A: pixel3_3)
return filter_out;
procedure compare
( H,V,LD,RD :in filter_out;
X: out filter_out;
Y: out filter_out;
Dir:out direction);
function magnitude
( A,B: filter_out)
return filter_out;
function int_to_stdlogic8
( A: integer)
return std_logic_vector;
function stdlogic_to_int
( s:std_logic_vector)
return INTEGER;
function int_to_stdlogic12
(A: integer)
return std_logic_vector;
end image_processing;
-- purpose: image processing package body description
-- (for BEH_INT and BEH_STRUC libraries
library IEEE;
use ieee.std_logic_1164.all;
---------------- package body description -----------------------
package body image_processing is
---------------- Horizontal_filter function ---------------------
function horizontal_filter
( A: pixel3_3)
return filter_out is
begin
return weight( A(1,1), A(1,2), A(1,3) )
-weight( A(3,1), A(3,2), A(3,3) );
end horizontal_filter;
---------------- Vertical_filter function -----------------------
function vertical_filter
( A: pixel3_3)
return filter_out is
begin
return weight( A(1,3), A(2,3), A(3,3))
-weight(A(1,1), A(2,1), A(3,1));
end vertical_filter;
---------------- Diagonal_l_filter function ---------------------
function diagonal_l_filter
( A:pixel3_3)
return filter_out is
begin
return weight( A(1,2), A(1,3), A(2,3))
-weight(A(2,1), A(3,1), A(3,2));
end diagonal_l_filter;
---------------- Diagonal_r_filter function ---------------------
function diagonal_r_filter
( A:pixel3_3)
return filter_out is
begin
return weight( A(1,2), A(1,1), A(2,1) )
-weight( A(2,3), A(3,3), A(3,2) );
end diagonal_r_filter;
---------------- Weight function ---------------------------------
function weight
( X1,X2,X3: pixel)
return filter_out is
begin
return X1+ 2*X2 + X3;
end weight;
---------------- Shift function ----------------------------------
function shift
( A: pix3;
B: pixel)
return pix3 is
begin
return A(2) & A(3) & B; -- CHANGED
end shift;
---------------- Compare procedure -------------------------------
procedure compare( H,V,LD,RD :in filter_out;
X: out filter_out;
Y: out filter_out;
Dir:out direction) is
variable AH: filter_out:=0;
variable AV: filter_out:=0;
variable ALD: filter_out:=0;
variable ARD: filter_out:=0;
variable C: filter_out:=0;
variable D: filter_out:=0;
variable direc: direction;
begin
-- get absolute values
if H <0 then
AH := -H;
elsif H>=2049 then
AH:=4096-H;
else
AH := H;
end if;
if V <0 then
AV := -V;
elsif V>=2049 then
AV:=4096-V;
else
AV := V;
end if;
if LD <0 then
ALD := -LD;
elsif LD>=2049 then
ALD:=4096-LD;
else
ALD := LD;
end if;
if RD <0 then
ARD := -RD;
elsif RD>=2049 then
ARD:=4096-RD;
else
ARD := RD;
end if;
-- get the maximum value
-- AH is the max
C:=AH;
D:=AV;
if H>0 then
direc:="010";
else
direc:="110";
end if;
-- AV is the max
if AV>C then
C:=AV;
D:=AH;
if V>0 then
direc:="000";
else
direc:="100";
end if;
end if;
-- ALD is the max
if ALD>C then
C:=ALD;
D:=ARD;
if LD > 0 then
direc:="001";
else
direc:="101";
end if;
end if;
-- ARD is the max
if ARD > C then
C:=ARD;
D:=ALD;
if RD >0 then
direc := "011";
else
direc := "111";
end if;
end if;
X:=C;
Y:=D;
dir:= direc;
end compare;
------------------------ Magnitude function -------------------------
function magnitude
(A,B: filter_out)
return filter_out is
begin
return (A + (B/8));
end magnitude;
----------- STD_ULOGIC_VECTOR TO INTEGER function ---------------------
function stdlogic_to_int(s:std_logic_vector) return INTEGER is
variable res : INTEGER:=0;
begin
for i in s'low to s'high loop
if s(i)='1' then
res:=res + (2 ** i);
end if;
end loop;
return res;
end stdlogic_to_int;
----------- INTEGER TO STD_ULOGIC_VECTOR( 7 downto 0) function -----------
function int_to_stdlogic8(A: integer) return std_logic_vector is
variable result : std_logic_vector(0 to 7):="00000000";
variable temp_a : integer:=0;
variable temp_b : integer:=0;
begin
temp_a := A;
for i in 7 downto 0 loop
temp_b:=temp_a/(2**i);
temp_a:=temp_a rem(2**i);
if(temp_b = 1) then
result(7-i):='1';
else
result(7-i):='0';
end if;
end loop;
return result;
end int_to_stdlogic8;
----------- INTEGER TO STD_ULOGIC_VECTOR(11 downto 0) function -----------
function int_to_stdlogic12(A: integer) return std_logic_vector is
variable result : std_logic_vector(0 to 11):="000000000000";
variable temp_a : integer:=0;
variable temp_b : integer:=0;
begin
temp_a := A;
for i in 11 downto 0 loop
temp_b:=temp_a/(2**i);
temp_a:=temp_a rem(2**i);
if(temp_b = 1) then
result(11-i):='1';
else
result(11-i):='0';
end if;
end loop;
return result;
end int_to_stdlogic12;
end image_processing;
-- executable specification of the Sobel edge detector
library IEEE;
use ieee.std_logic_1164.all;
----------------- interface declaration -----------------------------
entity edge_detector is
generic(threshold: filter_out; -- a threshold depend on which we define the
-- edge pexels
num_rows:natural; -- the number of rows of the image file
num_cols: natural); -- the number of columns of the image file
port(clock: in Std_ulogic; -- the system CLOCK
edge_start : in std_logic:='0'; -- the START signal for the image
-- processing
input: in pixel; -- input pixel
output: out pixel; -- output pixel
dir : out direction); -- output direction
end edge_detector;
----------------- architecture body description ---------------------
architecture behavior of edge_detector is
type memory_array is array(1 to 3, 1 to num_cols) of pixel;
begin
sobel: process
variable busy1,busy2 : std_logic:='0'; -- internal BUSY variable
variable A : pixel3_3:=((0,0,0),(0,0,0),(0,0,0)); -- temporary storage for
-- the input pixels
variable temp : pixel; -- temporary storage for the output pixel
variable E_H : filter_out; -- temporary storage for results of
-- horizontal filter
variable E_V : filter_out; -- temporary storage for results of
-- vertical filter
variable E_DL : filter_out; -- temporary storage for results of
-- left_diagonal filter
variable E_DR : filter_out; -- temporary storage for results of
-- right_diagonal filter
variable M : filter_out; -- temporary storage for results of
-- Max abs value of the filters
variable P : filter_out; -- temporary storage for results of
-- of the perpendicular of the max
-- value of the filters
variable Mag : filter_out;
variable phase: direction;
variable x1,y1,x2,y2:natural:=1;
variable count_r1,count_r2:integer:=0;
variable count:natural:=0;
variable memory: memory_array;
-------- filtering, calculating the magnitude, determine the edge pixel ------
begin
wait until rising_edge(clock);
if edge_start ='1' then
busy1:='1';
end if;
-------- store the input image data in a memory array -------------------------
if busy1 ='1' then
memory(x1,y1):=input;
if count_r1=2 and y1=1 then
busy2:='1';
end if;
y1:=y1+1;
if y1=num_cols+1 then
y1:=1;
x1:=x1+1;
count_r1:=count_r1+1;
end if;
if x1=4 then
x1:=1;
end if;
if count_r1=num_rows then
busy1:='0';
end if;
end if;
------ read the 9 data of the memory array to a buffer for filtering ------
if busy2='1' then
for j in 1 to 2 loop
for i in 1 to 3 loop
A(i,j):= A(i,j+1);
end loop;
end loop;
for i in 1 to 3 loop
A(i,3):=memory((count_r2 +i-1)mod 3+1,y2);
end loop;
y2:=y2+1;
if y2=num_cols+1 then
count_r2:=count_r2+1;
y2:=1;
end if;
if count_r2 = num_rows-2 then
busy2 := '0';
end if;
--------- apply the filtering function to the input image data ---------------
E_H := horizontal_filter(A);
E_V := vertical_filter(A);
E_DL := diagonal_l_filter(A);
E_DR := diagonal_r_filter(A);
--------- get the output edge pixels and directions --------------------------
compare(E_H,E_V,E_DL,E_DR,M,P,phase);
Mag:= magnitude(M,P);
if Mag >= threshold then
temp := foreground;
else
temp := background;
end if;
output <= temp;
dir <= phase;
end if;
end process sobel;
end behavior;
-- Test Bench for SOBEL behavioral model
-- Figures 11.19 through 11.26
library IEEE;
use ieee.std_logic_1164.all;
use std.textio.all;
entity test is
generic(in_file :string(1 to 11); -- input image file
out_file :string(1 to 11); -- output file for storing magnitude
-- outputs
dir_file :string(1 to 11); -- output file which stores direction
-- outputs of bit_vector type
num_rows :natural; -- number of rows in the input image
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -