目次

画像処理下準備2

 画像データの1ライン中の最大値、最小値を求め
 2値化を高速するVHDLコードを作成しました。

 1ピクセルを8ビットとして、8ビットの画像
 データを与えるごとに、最大値、最小値を計算
 して出力します。

 リセット後、最大値、最小値を255、0に設定し
 8ビット画像データをトリガーと共に与えると
 2クロック後、更新した最大値、最小値を出力
 します。

 新しいラインの最大値、最小値を求めるために
 一度初期化します。



 利用する信号線は、以下。

 作成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ビットで指定します。フォーマット指定
 は、次の組合わせとしました。

 図で示すとエンティティは、単純です。



 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の各データの変化
 を見ながら、動作確認できます。


目次

inserted by FC2 system