volisyon kerneli olarak adlandırılan bir matris ile çarpımıyla elde edilir. Konvolisyon işlemine ilişkin denklem aşağıda verilmiştir.


Şekil 1 Konvolüsyon işlemi

Şekil 1’de verilen örnek piksel değeri ve konvolüsyon kerneline ilişkin hesaplama aşağıdaki gibi yapılmatakdır.

Örnek : Aşağıda imge de konvolüsyon işleminin gerçekleştirildiği konvolusyon_imge.vhd VHDL kodu verilmiştir. Kodda RAM üzerinden okunan datalar 3×3 matriste saklanmaktadır. Matriste bulunan datalar konvolusyon işlemine tabi tutularak işlem sonucu elde edilmektedir.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.konvolusyon_imge_paket.all; entity konvolusyon_imge is port( in_clk : in std_logic; in_rst : in std_logic; in_en : in std_logic; in_basla : in std_logic; in_data : in std_logic_vector(VERI_UZUNLUGU - 1 downto 0); in_data_vld : in std_logic; in_kernel : in std_logic_vector(2 downto 0); out_addr : out std_logic_vector(log2_int(IMGE_SATIR * IMGE_SUTUN) - 1 downto 0); out_addr_vld : out std_logic; out_data : out std_logic_vector(7 downto 0); out_data_vld : out std_logic; out_tamam : out std_logic ); end konvolusyon_imge; architecture Behavioral of konvolusyon_imge is type t_Konvolusyon_Imge is (BOSTA, RAMDAN_OKU, OKUMA_BEKLE, MATRIS_KAYDIR, KONV_HESAPLA, SAYAC_KONT, TAMAM ); signal r_Konvolusyon_Imge : t_Konvolusyon_Imge := RAMDAN_OKU; signal VERI : m_VERI_MATRISI := (others => (others => (others => '0'))); signal Tek_Sutun : v_VERI_DIZISI := (others => (others => '0')); signal n_i : integer := 0; signal n_j : integer := 0; signal n_k : integer := 0; signal n_s : integer := 0; signal r_addr : std_logic_vector(log2_int(IMGE_SATIR * IMGE_SUTUN) - 1 downto 0) := (others => '0'); signal r_addr_vld : std_logic := '0'; signal r_data : std_logic_vector(7 downto 0) := (others => '0'); signal r_data_vld : std_logic := '0'; signal r_bayrak_oku : std_logic := '0'; signal r_kenar_bulma_tmm : std_logic := '0'; signal r_tamam : std_logic := '0'; begin out_addr <= r_addr; out_addr_vld <= r_addr_vld; out_data <= r_data; out_data_vld <= r_data_vld; out_tamam <= r_tamam; process(in_clk, in_rst, in_en) begin if in_rst = '1' then Tek_Sutun <= (others => (others => '0')); n_s <= 0; r_bayrak_oku <= '0'; elsif rising_edge(in_clk) then if in_en = '1' then if in_data_vld = '1' then Tek_Sutun(n_s) <= in_data; n_s <= n_s + 1; if n_s = 2 then n_s <= 0; r_bayrak_oku <= '1'; end if; else r_bayrak_oku <= '0'; end if; end if; end if; end process; process(in_clk, in_rst) begin if in_rst = '1' then VERI <= (others => (others => (others => '0'))); r_Konvolusyon_Imge <= BOSTA; n_i <= 0; n_j <= 0; r_addr <= (others => '0'); r_addr_vld <= '0'; r_data <= (others => '0'); r_data_vld <= '0'; r_tamam <= '0'; n_k <= 0; elsif rising_edge(in_clk) then if in_en = '1' then r_addr_vld <= '0'; r_data_vld <= '0'; r_tamam <= '0'; case r_Konvolusyon_Imge is when BOSTA => if in_basla = '1' then r_Konvolusyon_Imge <= RAMDAN_OKU; end if; when RAMDAN_OKU => r_addr <= conv_std_logic_vector((n_i + n_k) * IMGE_SUTUN + n_j, r_addr'length); r_addr_vld <= '1'; n_k <= n_k + 1; if n_k = 2 then r_Konvolusyon_Imge <= OKUMA_BEKLE; end if; when OKUMA_BEKLE => n_k <= 0; if r_bayrak_oku = '1' then r_Konvolusyon_Imge <= MATRIS_KAYDIR; end if; when MATRIS_KAYDIR => n_j <= n_j + 1; VERI <= f_Matris_Kaydır(VERI, Tek_Sutun); if n_j < 2 then r_Konvolusyon_Imge <= RAMDAN_OKU; else r_Konvolusyon_Imge <= KONV_HESAPLA; end if; when KONV_HESAPLA => r_data <= f_Konvolusyon_Imge(VERI, r_KERNEL_LISTE(conv_integer(in_kernel))); r_data_vld <= '1'; r_Konvolusyon_Imge <= SAYAC_KONT; if n_j = IMGE_SUTUN then n_i <= n_i + 1; n_j <= 0; end if; when SAYAC_KONT => r_data_vld <= '0'; if n_i < IMGE_SATIR - 2 then r_Konvolusyon_Imge <= RAMDAN_OKU; else n_i <= 0; r_Konvolusyon_Imge <= TAMAM; end if; when TAMAM => r_tamam <= '1'; r_Konvolusyon_Imge <= BOSTA; when others => NULL; end case; end if; end if; end process; end Behavioral;
Bu örnekte tip, fonksiyon, sabit vb tanımlama işlemleri konvolusyon_imge_paket.vhd paketi içerisinde yapılmıştır. Aşağıda bu pakete ilişkin kod verilmiştir.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; package konvolusyon_imge_paket is constant IMGE_SATIR : integer := 256; constant IMGE_SUTUN : integer := 256; constant VERI_UZUNLUGU : integer := 8; type v_VERI_DIZISI is array (0 to 2) of std_logic_vector(VERI_UZUNLUGU - 1 downto 0); type m_VERI_MATRISI is array (0 to 2) of v_VERI_DIZISI; type v_KERNEL_DIZISI is array (0 to 2) of integer; type m_KERNEL_MATRISI is array (0 to 2) of v_KERNEL_DIZISI; type t_KERNEL_LISTE is array (0 to 7) of m_KERNEL_MATRISI; constant r_KERNEL_LISTE : t_KERNEL_LISTE := (((1, 2, 1), (0, 0, 0), (-1, -2, -1)), ((1, 0, -1), (2, 0, -2), (1, 0, -1)), ((1, 1, 1), (0, 0, 0), (-1, -1, -1)), ((1, 0, -1), (2, 0, -2), (1, 0, -1)), ((0, 0, 0), (0, 1, 0), (0, 0, -1)), ((0, 1, 0), (1, 0, 1), (0, 1, 0)), ((-1, -1, -1), (-1, 8, -1), (-1, -1, -1)), ((1, 2, 1), (2, 4, 2), (1, 2, 1))); constant YATAY_SOBEL : std_logic_vector(2 downto 0) := "000"; constant DIKEY_SOBEL : std_logic_vector(2 downto 0) := "001"; constant YATAY_PREWIT : std_logic_vector(2 downto 0) := "010"; constant DIKEY_PREWIT : std_logic_vector(2 downto 0) := "011"; constant KAYDIR_CIKART : std_logic_vector(2 downto 0) := "100"; constant ALCAK_GECIREN : std_logic_vector(2 downto 0) := "101"; constant YUKSEK_GECIREN : std_logic_vector(2 downto 0) := "110"; constant GAUSS : std_logic_vector(2 downto 0) := "111"; function log2_int(in_giris : integer) return integer; function f_Matris_Kaydır(Kernel : m_VERI_MATRISI; Tek_Sutun : v_VERI_DIZISI) return m_VERI_MATRISI; function f_Konvolusyon_Imge(VERI : m_VERI_MATRISI; KERNEL : m_KERNEL_MATRISI) return std_logic_vector; end konvolusyon_imge_paket; package body konvolusyon_imge_paket is function f_Konvolusyon_Imge(VERI : m_VERI_MATRISI; KERNEL : m_KERNEL_MATRISI) return std_logic_vector is variable Toplam : integer; begin Toplam := 0; for n_i in 0 to 2 loop for n_j in 0 to 2 loop Toplam := Toplam + conv_integer(VERI(n_i)(n_j)) * KERNEL(2 - n_i)(2 - n_j); end loop; end loop; if Toplam > 255 then Toplam := 255; elsif Toplam < 0 then Toplam := 0; end if; return conv_std_logic_vector(Toplam, 8); end f_Konvolusyon_Imge; function f_Matris_Kaydir(Kernel : m_VERI_MATRISI; Tek_Sutun : v_VERI_DIZISI) return m_VERI_MATRISI is variable Kernel_v : m_VERI_MATRISI; variable Tek_Sutun_v : v_VERI_DIZISI; begin Kernel_v := Kernel; Tek_Sutun_v := Tek_Sutun; for n_j in 0 to 1 loop for n_i in 0 to 2 loop Kernel_v(n_i)(n_j) := Kernel_v(n_i)(n_j + 1); end loop; end loop; for n_j in 0 to 2 loop Kernel_v(n_j)(2) := Tek_Sutun_v(n_j); end loop; return Kernel_v; end f_Matris_Kaydir; function log2_int(in_giris : integer) return integer is variable sonuc : integer; begin for n_i in 0 to 31 loop if (in_giris <= (2 ** n_i)) then sonuc := n_i; exit; end if; end loop; return sonuc; end function; end package body;
konvolusyon_imge varlığının benzetiminin yapılabilmesi için aşağıda tb_konvolusyon_imge.vhd VHDL sınama kodu verilmiştir. Kodda dosyadan okunan imge dataları RAM bloğuna yazılmaktadır. Benzetim işlemleri sonuçları Şekil 2’de gösterilmiştir.
- Şekil 2.a’da orijinal imge,
- Şekil 2.b’de yatay Sobel kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.c’de dikey Sobel kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.d’de yatay Prewit kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.e’de dikey Prewit kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.f’de kaydır ve çıkart kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.g’de alçak geçiren süzgeç kerneli ile konvolüsyon sonucunda elde edilen yeni imge,
- Şekil 2.h’de yüksek geçiren süzgeç kerneli ile konvolüsyon sonucunda elde edilen yeni imge ve
- Şekil 2.i’de gauss kerneli ile konvolüsyon sonucunda elde edilen yeni imge gösterilmiştir.
![]() (a) | ![]() (b) | ![]() (c) |
![]() (d) | ![]() (e) | ![]() (f) |
![]() (g) | ![]() (h) | ![]() (i) |
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use std.textio.ALL; use work.konvolusyon_imge_paket.all; entity tb_konvolusyon_imge is end tb_konvolusyon_imge; architecture Behavioral of tb_konvolusyon_imge is component konvolusyon_imge port( in_clk : in std_logic; in_rst : in std_logic; in_en : in std_logic; in_basla : in std_logic; in_data : in std_logic_vector(VERI_UZUNLUGU - 1 downto 0); in_data_vld : in std_logic; in_kernel : in std_logic_vector(2 downto 0); out_addr : out std_logic_vector(log2_int(IMGE_SATIR * IMGE_SUTUN) - 1 downto 0); out_addr_vld : out std_logic; out_data : out std_logic_vector(7 downto 0); out_data_vld : out std_logic; out_tamam : out std_logic ); end component; component block_ram generic( VERI_UZUNLUGU : integer := 8; RAM_DERINLIGI : integer := 110 ); port( in_clk : in std_logic; in_rst : in std_logic; in_ram_aktif : in std_logic; in_yaz_en : in std_logic; in_oku_en : in std_logic; in_data_addr : in std_logic_vector(log2_int(RAM_DERINLIGI) - 1 downto 0); in_data : in std_logic_vector(VERI_UZUNLUGU - 1 downto 0); out_data : out std_logic_vector(VERI_UZUNLUGU - 1 downto 0); out_data_vld : out std_logic ); end component; constant CLK_PERIOD : time := 20 ns; constant VERI_YOLU_OKUMA : string := "C:\cameraman.txt"; constant VERI_YOLU_YAZMA : string := "D:\cameraman_sonuc.txt"; type t_Konvolusyon_Imge is (RAM_OKUMA, RAM_YAZMA, TAMAM); signal r_Konvolusyon_Imge : t_Konvolusyon_Imge := RAM_YAZMA; signal in_clk : std_logic := '0'; signal in_rst : std_logic := '0'; signal in_basla : std_logic := '0'; signal in_ram_aktif : std_logic := '1'; signal out_data_vld : std_logic := '0'; signal out_data : std_logic_vector(7 downto 0) := (others => '0'); signal in_ram_data : std_logic_vector(VERI_UZUNLUGU - 1 downto 0) := (others => '0'); signal in_ram_data_addr : std_logic_vector(log2_int(IMGE_SATIR * IMGE_SUTUN) - 1 downto 0) := (others => '0'); signal out_ram_data : std_logic_vector(VERI_UZUNLUGU - 1 downto 0) := (others => '0'); signal out_data_addr : std_logic_vector(log2_int(IMGE_SATIR * IMGE_SUTUN) - 1 downto 0) := (others => '0'); signal out_ram_data_vld : std_logic := '0'; signal in_en : std_logic := '0'; signal in_yaz_en : std_logic := '0'; signal in_oku_en : std_logic := '0'; signal data_sayac : integer := 0; signal out_data_addr_vld : std_logic := '0'; signal r_imge_isleme_tamam : std_logic := '0'; begin process begin in_clk <= '1'; wait for CLK_PERIOD / 2; in_clk <= '0'; wait for CLK_PERIOD / 2; end process; process begin in_basla <= '1'; wait for CLK_PERIOD; in_basla <= '0'; wait; end process; process(in_clk) file dosya_okuma : text open read_mode is VERI_YOLU_OKUMA; file dosya_yazma : text open write_mode is VERI_YOLU_YAZMA; variable satir_okuma : line; variable satir_yazma : line; variable data_okuma : integer; begin if rising_edge(in_clk) then if out_data_vld = '1' then write(satir_yazma, conv_integer(out_data)); writeline(dosya_yazma, satir_yazma); end if; case r_Konvolusyon_Imge is when RAM_YAZMA => if not endfile(dosya_okuma) then readline(dosya_okuma, satir_okuma); read(satir_okuma, data_okuma); in_ram_data <= conv_std_logic_vector(data_okuma, VERI_UZUNLUGU); in_ram_data_addr <= conv_std_logic_vector(data_sayac, in_ram_data_addr'length); in_en <= '0'; in_yaz_en <= '1'; data_sayac <= data_sayac + 1; else r_Konvolusyon_Imge <= RAM_OKUMA; in_yaz_en <= '0'; end if; when RAM_OKUMA => in_en <= '1'; in_ram_data_addr <= out_data_addr; in_oku_en <= out_data_addr_vld ; if r_imge_isleme_tamam = '1' then r_Konvolusyon_Imge <= TAMAM; end if; when TAMAM => null; when others => NULL; end case; end if; end process; konvolusyon_imge_map : konvolusyon_imge port map( in_clk => in_clk, in_rst => in_rst, in_en => in_en, in_basla => in_basla, in_data => out_ram_data, in_data_vld => out_ram_data_vld, in_kernel => GAUSS, out_addr => out_data_addr, out_addr_vld => out_data_addr_vld, out_data => out_data, out_data_vld => out_data_vld, out_tamam => r_imge_isleme_tamam ); block_ram_map : block_ram generic map( VERI_UZUNLUGU => VERI_UZUNLUGU, RAM_DERINLIGI => IMGE_SATIR * IMGE_SUTUN ) port map( in_clk => in_clk, in_rst => in_rst, in_ram_aktif => in_ram_aktif, in_yaz_en => in_yaz_en, in_oku_en => in_oku_en, in_data_addr => in_ram_data_addr, in_data => in_ram_data, out_data => out_ram_data, out_data_vld => out_ram_data_vld ); end Behavioral;
Blok RAM yazımızda verilen block_ram.vhd VHDL dosyasında 4. satırda bulunan paket tanımlama ifadesi aşğıda verilen ifade ile değiştirilmelidir.
use work.konvolusyon_imge_paket.all;
Aşağıda dosyadan imge okuma işleminin yapıldığı MATLAB kodu verilmiştir.
clc, clear all, close all; imge = imread('cameraman.tif'); imshow(imge) [satir sutun] = size(imge); dosya = fopen('D:\cameraman_sonuc.txt', 'r'); imge_okunan = fscanf(dosya, '%d')'; COEF = [-1 -2 -1; 0 0 0; 1 2 1]; for n_i = 1 : satir - 2 for n_j = 1 : sutun - 2 yeni_imge(n_i, n_j) = imge_okunan((n_i - 1) * (sutun - 2) + n_j); end end fclose(dosya); figure, imshow(uint8(yeni_imge))