目次
前
次
画像処理下準備2
画像データの1ライン中の最大値、最小値を求め
2値化を高速するVHDLコードを作成しました。
1ピクセルを8ビットとして、8ビットの画像
データを与えるごとに、最大値、最小値を計算
して出力します。
リセット後、最大値、最小値を255、0に設定し
8ビット画像データをトリガーと共に与えると
2クロック後、更新した最大値、最小値を出力
します。
新しいラインの最大値、最小値を求めるために
一度初期化します。
利用する信号線は、以下。
- TRG データ指定用トリガー
- CLR 最大値、最小値の初期化トリガー
作成VHDLコードは、次のようになります。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity minmax is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- trigger
TRG : in std_logic ;
CLR : in std_logic ;
-- data
DINX : in std_logic_vector(7 downto 0) ;
-- output
MIN : out std_logic_vector(7 downto 0) ;
MAX : out std_logic_vector(7 downto 0) --;
);
end minmax;
architecture Behavioral of minmax is
-- trigger
signal iTRG : std_logic ;
signal iTRG_SFT : std_logic_vector(2 downto 0) ;
signal iCLR : std_logic ;
signal iCLR_SFT : std_logic_vector(2 downto 0) ;
-- result
signal iMIN : std_logic_vector(7 downto 0) ;
signal iMAX : std_logic_vector(7 downto 0) ;
-- temporary
signal iDIN : std_logic_vector(7 downto 0) ;
-- sequencer
signal iSTATE : std_logic_vector(1 downto 0) ;
begin
-- output
MIN <= iMIN ;
MAX <= iMAX ;
-- trigger
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iTRG_SFT <= "000" ;
iCLR_SFT <= "000" ;
elsif falling_edge( CLOCK ) then
iTRG_SFT <= iTRG_SFT(1 downto 0) & TRG ;
iCLR_SFT <= iCLR_SFT(1 downto 0) & CLR ;
end if ;
end process ;
iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;
iCLR <= '1' when ( iCLR_SFT = "011" or iCLR_SFT = "001" ) else '0' ;
-- get data
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
iDIN <= (others => '0') ;
iMIN <= (others => '1') ;
iMAX <= (others => '0') ;
elsif rising_edge( CLOCK ) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iTRG = '1' ) then
iSTATE <= "01" ;
elsif ( iCLR = '1' ) then
iSTATE <= "10" ;
iDIN <= (others => '0') ;
iMIN <= (others => '1') ;
iMAX <= (others => '0') ;
else
iSTATE <= "00" ;
end if ;
-- latch
when 1 => iSTATE <= "11" ;
iDIN <= DINX ;
-- update
when 3 => iSTATE <= "10" ;
if ( conv_integer(iMAX) < conv_integer(iDIN) ) then
iMAX <= iDIN ;
end if ;
if ( conv_integer(iMIN) > conv_integer(iDIN) ) then
iMIN <= iDIN ;
end if ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
end Behavioral;
FPGA内部に、最大値、最小値を求める回路を
試験する回路も定義しました。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tstminmax is
generic (
TOPX : integer := 18 ;
XMAX : integer := 240000 --;
);
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- trigger
TRG : in std_logic ;
CLR : in std_logic ;
INIT : in std_logic ;
-- data
DOUTX : out std_logic_vector(7 downto 0) ;
-- output
MIN : out std_logic_vector(7 downto 0) ;
MAX : out std_logic_vector(7 downto 0) --;
);
end tstminmax;
architecture Behavioral of tstminmax is
-- trigger
component clkgenx is
generic (
TOPX : integer ;
RMAX : integer --;
);
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- output
CLKOUT : out std_logic -- ;
);
end component ;
component minmax is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- trigger
TRG : in std_logic ;
CLR : in std_logic ;
-- data
DINX : in std_logic_vector(7 downto 0) ;
-- output
MIN : out std_logic_vector(7 downto 0) ;
MAX : out std_logic_vector(7 downto 0) --;
);
end component ;
-- clock
signal iSCLK : std_logic ;
-- trigger
signal iTRG : std_logic ;
signal iTRG_SFT : std_logic_vector(2 downto 0) ;
signal iCLR : std_logic ;
signal iCLR_SFT : std_logic_vector(2 downto 0) ;
-- sequencer
signal iCNT : integer range 0 to 8 ;
signal iSTATE : std_logic_vector(1 downto 0) ;
-- internal data
signal iDATA : std_logic_vector(7 downto 0) ;
signal iMMTRG : std_logic ;
-- result
signal iMIN : std_logic_vector(7 downto 0) ;
signal iMAX : std_logic_vector(7 downto 0) ;
begin
-- component
CLKX : clkgenx generic map (TOPX,XMAX) port map (nRESET,CLOCK,iSCLK) ;
MMX : minmax port map (nRESET,iSCLK,iMMTRG,INIT,iDATA,iMIN,iMAX) ;
-- sequencer
process (nRESET,iSCLK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
iCNT <= 0 ;
elsif rising_edge( iSCLK ) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iTRG = '1' ) then
iSTATE <= "01" ;
elsif ( iCLR = '1' ) then
iSTATE <= "10" ;
iCNT <= 0 ;
else
iSTATE <= "00" ;
end if ;
-- set data
when 1 => iSTATE <= "11" ;
-- send trigger
when 3 => iSTATE <= "10" ;
iCNT <= iCNT + 1 ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
iMMTRG <= '1' when ( iSTATE = "11" ) else '0' ;
iDATA <= X"10" when ( iCNT = 0 ) else
X"02" when ( iCNT = 1 ) else
X"40" when ( iCNT = 2 ) else
X"08" when ( iCNT = 3 ) else
X"01" when ( iCNT = 4 ) else
X"20" when ( iCNT = 5 ) else
X"04" when ( iCNT = 6 ) else
X"80" when ( iCNT = 7 ) else
X"00" ;
-- output
MIN <= not iMIN ;
MAX <= not iMAX ;
DOUTX <= not iDATA ;
-- trigger
process (nRESET,iSCLK)
begin
if ( nRESET = '0' ) then
iTRG_SFT <= "000" ;
iCLR_SFT <= "000" ;
elsif rising_edge( iSCLK ) then
iTRG_SFT <= iTRG_SFT(1 downto 0) & TRG ;
iCLR_SFT <= iCLR_SFT(1 downto 0) & CLR ;
end if ;
end process ;
iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;
iCLR <= '1' when ( iCLR_SFT = "011" or iCLR_SFT = "001" ) else '0' ;
end Behavioral;
データを8個用意し、トリガーを与える毎に
最大値、最小値を求める回路に渡します。
スイッチとLEDを並べた基板を接続して
テストするため、与えるデータと最大値
最小値は、負論理で出力して表示します。
今回利用するカメラは、RGBフォーマットで画像
データを出力できます。
16ビットの中にRGBの各ビット幅は、6、5、4の
いずれかで組み合わせは、RGB565、RGB555、RGB444
となっています。
16ビットから、どのフォーマットで各色ビットを抽出
するかを、2ビットで指定します。フォーマット指定
は、次の組合わせとしました。
- 11 RGB565フォーマット
- 10 RGB555フォーマット
- 01 RGB444フォーマット
- 00 すべて0を出力
図で示すとエンティティは、単純です。
VHDLコードは、以下です。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity gsep is
Port (
-- function
FUNC : in std_logic_vector(1 downto 0) ;
-- graphic data
Din : in std_logic_vector(15 downto 0) ;
-- OUTPUT
ROut : out std_logic_vector(5 downto 0) ;
GOut : out std_logic_vector(5 downto 0) ;
BOut : out std_logic_vector(5 downto 0) --;
);
end gsep;
architecture behavioral of gsep is
-- buffer
signal iROut : std_logic_vector(5 downto 0) ;
signal iGOut : std_logic_vector(5 downto 0) ;
signal iBOut : std_logic_vector(5 downto 0) ;
begin
-- output
ROut <= iROut ;
GOut <= iGOut ;
BOut <= iBOut ;
-- separate
iROut <= ('0' & Din(15 downto 11)) when ( FUNC = "11" ) else -- RGB565
('0' & Din(14 downto 10)) when ( FUNC = "10" ) else -- RGB555
("00" & Din(11 downto 8)) when ( FUNC = "01" ) else -- RGB444
"000000" ;
iGOut <= Din(10 downto 5) when ( FUNC = "11" ) else -- RGB565
('0' & Din(9 downto 5)) when ( FUNC = "10" ) else -- RGB555
("00" & Din(7 downto 4)) when ( FUNC = "01" ) else -- RGB444
"000000" ;
iBOut <= ('0' & Din(4 downto 0)) when ( FUNC = "11" ) else -- RGB565
('0' & Din(4 downto 0)) when ( FUNC = "10" ) else -- RGB555
("00" & Din(3 downto 0)) when ( FUNC = "01" ) else -- RGB444
"000000" ;
end behavioral;
FPGA内部に、色ビットを切り出す回路を
試験する回路も定義しました。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tstminmax is
generic (
TOPX : integer := 18 ;
XMAX : integer := 240000 --;
);
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- trigger
TRG : in std_logic ;
CLR : in std_logic ;
-- function
FUNC : in std_logic_vector(1 downto 0) ;
-- output
Rout : out std_logic_vector(5 downto 0) ;
Gout : out std_logic_vector(5 downto 0) ;
Bout : out std_logic_vector(5 downto 0) --;
);
end tstminmax;
architecture Behavioral of tstminmax is
-- trigger
component clkgenx is
generic (
TOPX : integer ;
RMAX : integer --;
);
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- output
CLKOUT : out std_logic -- ;
);
end component ;
component gsep is
port (
-- function
FUNC : in std_logic_vector(1 downto 0) ;
-- graphic data
Din : in std_logic_vector(15 downto 0) ;
-- OUTPUT
ROut : out std_logic_vector(5 downto 0) ;
GOut : out std_logic_vector(5 downto 0) ;
BOut : out std_logic_vector(5 downto 0) --;
);
end component ;
-- clock
signal iSCLK : std_logic ;
-- trigger
signal iTRG : std_logic ;
signal iTRG_SFT : std_logic_vector(2 downto 0) ;
signal iCLR : std_logic ;
signal iCLR_SFT : std_logic_vector(2 downto 0) ;
-- sequencer
signal iCNT : integer range 0 to 16 ;
signal iSTATE : std_logic_vector(1 downto 0) ;
-- internal data
signal iDATA : std_logic_vector(15 downto 0) ;
-- result
signal iR : std_logic_vector(5 downto 0) ;
signal iG : std_logic_vector(5 downto 0) ;
signal iB : std_logic_vector(5 downto 0) ;
begin
-- component
CLKX : clkgenx generic map (TOPX,XMAX) port map (nRESET,CLOCK,iSCLK) ;
GSEPX : gsep port map (FUNC,iDATA,iR,iG,iB);
-- sequencer
process (nRESET,iSCLK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
iCNT <= 0 ;
elsif rising_edge( iSCLK ) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iTRG = '1' ) then
iSTATE <= "01" ;
elsif ( iCLR = '1' ) then
iSTATE <= "10" ;
iCNT <= 0 ;
else
iSTATE <= "00" ;
end if ;
-- set data
when 1 => iSTATE <= "11" ;
-- send trigger
when 3 => iSTATE <= "10" ;
iCNT <= iCNT + 1 ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
iDATA <= X"0001" when ( iCNT = 0 ) else
X"0002" when ( iCNT = 1 ) else
X"0004" when ( iCNT = 2 ) else
X"0008" when ( iCNT = 3 ) else
X"0010" when ( iCNT = 4 ) else
X"0020" when ( iCNT = 5 ) else
X"0040" when ( iCNT = 6 ) else
X"0080" when ( iCNT = 7 ) else
X"0100" when ( iCNT = 8 ) else
X"0200" when ( iCNT = 9 ) else
X"0400" when ( iCNT = 10 ) else
X"8000" when ( iCNT = 11 ) else
X"1000" when ( iCNT = 12 ) else
X"2000" when ( iCNT = 13 ) else
X"4000" when ( iCNT = 14 ) else
X"8000" when ( iCNT = 15 ) else
X"0000" ;
-- output
Rout <= not iR ;
Gout <= not iG ;
Bout <= not iB ;
-- trigger
process (nRESET,iSCLK)
begin
if ( nRESET = '0' ) then
iTRG_SFT <= "000" ;
iCLR_SFT <= "000" ;
elsif rising_edge( iSCLK ) then
iTRG_SFT <= iTRG_SFT(1 downto 0) & TRG ;
iCLR_SFT <= iCLR_SFT(1 downto 0) & CLR ;
end if ;
end process ;
iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;
iCLR <= '1' when ( iCLR_SFT = "011" or iCLR_SFT = "001" ) else '0' ;
end Behavioral;
FUNCで、画像フォーマットを指定し、トリガー
ボタンを押すたびに、16ビットデータ中の1の
位置を下位から上位に移動させます。
単純ですが、1があるビット位置がボタンを押す
毎にシフトしていくので、RGBの各データの変化
を見ながら、動作確認できます。
目次
前
次