FC2カウンター FPGAの部屋 画像のエッジ検出7(3X3演算のシミュレーション)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

画像のエッジ検出7(3X3演算のシミュレーション)

3X3演算のVHDLコードは昨日できたんだけど、もう朝食の時間になってしまったので、シミュレーションができなかった。今日はシミュレーションの結果を書いておこうと思う。
このシミュレーションの最中にBRAMによるダブルバッファリングのアドレスのコードにバグが見つかった。1水平ラインについて切り替えるはずが、1フレームで切り替えとなっていた。これは、画像のエッジ検出4(実機でテスト)”と画像のエッジ検出5(2X2の画素の演算でやってみた)”に影響する。後で、記事を書き換えるつもりなので、よろしくお願いします。しかし、”画像のエッジ検出4(実機でテスト)”は正常にエッジが検出出来ていたように見えたのだが、なんでだろう?(追記:これは修正されていました)

ともかく今回の、3X3演算のVHDLコードの主要な部分を下に示す。

    Xnp1Ynm1    <= bram_data2;
    Xnp1Yn        <= bram_data;
    Xnp1Ynp1    <= cam_ydata_2d;
    -- 1クロック前のBRAMの出力と現在の値の1クロック前の値を保持
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                Xnm1Ynm1    <= (others => '0');
                XnYnm1        <= (others => '0');
                Xnm1Yn        <= (others => '0');
                XnYn        <= (others => '0');
                Xnm1Ynp1    <= (others => '0');
                XnYnp1        <= (others => '0');
            else
                if r_w='1' then
                    Xnm1Ynm1    <= XnYnm1;
                    XnYnm1        <= Xnp1Ynm1;
                    Xnm1Yn        <= XnYn;
                    XnYn        <= Xnp1Yn;
                    Xnm1Ynp1    <= XnYnp1;
                    XnYnp1        <= Xnp1Ynp1;
                end if;
            end if;
        end if;
    end process;
    
    Laplacian_cal_val <= "01000"*(XnYn) - ("00000"&Xnm1Ynm1) - ("00000"&XnYnm1) - ("00000"&Xnp1Ynm1) - ("00000"&Xnm1Yn) - ("00000"&Xnp1Yn) - ("00000"&Xnm1Ynp1) - ("00000"&XnYnp1) - ("00000"&Xnp1Ynp1) ;
    -- マトリクスの絶対値
    process(Laplacian_cal_val) begin
        if Laplacian_cal_val(12)='1' then -- 負の値
            abs_Laplacian_cal_val <= not(Laplacian_cal_val-1);
        else -- 正の数
            abs_Laplacian_cal_val <= Laplacian_cal_val;
        end if;
    end process;

    ydata_out <= x"00" when h_valid_flag='0' or v_valid_flag='0' else
        x"FF" when (abs_Laplacian_cal_val(12) or abs_Laplacian_cal_val(11) or abs_Laplacian_cal_val(10) or abs_Laplacian_cal_val(9) or abs_Laplacian_cal_val(8))='1'
        else abs_Laplacian_cal_val(7 downto 0); -- 飽和演算


いずれは、汎用的な3X3演算器を目指すのだが、とりあえずはベタで書いてある。BRAMは2つインスタンシエーションしてあり、bram_data が下図のBRAM1のReadデータ出力、bram_data2 が下図のBRAM2のReadデータ出力に相当する。Xnm1Ynm1 はXn-1Yn-1に相当し、Xnp1Ynp1 はXn+1Yn+1 に相当する。
edge_detect_12_091113.png

h_valid_flag は1水平ラインで2つの輝度(Y)データが来たら1となる。それまではydata_out出力は0になる。v_valid_flag は2水平ラインまで0で、3水平ラインから1になる。それまでは、ydata_out出力は0になる。
下にCamera_Controller モジュールのシミュレーション波形を示す。
edge_detect_13_091113.png

上の図で、ピンクの四角はcam_ydata_2d のうちの輝度データの位置を示す。そのうちのカーソルに位置の演算(水色の四角)を検算してみることにする。

Xn-1Yn-1 = 01
XnYn-1  = 02
Xn+1Y-1 = 04
Xn-1Yn  = 02
XnYn    = 03
Xn+1Yn  = 04
Xn-1Yn+1 = 82
XnYn+1  = 04
Xn+1Yn+1 = 08


なので、
-------------
| -1| -1| -1|
-------------
| -1| 8| -1|
-------------
| -1| -1| -1|
-------------

は、03*8 - 01 - 02 - 04 - 02 - 04 - 82 - 04 - 08 = 1F7D (laplacian_cal_val)
絶対値 (abs_laplacian_cal_val)は0083 で検算結果と合う。
これで実機で確かめてみようと思うが、忙しいのでどうなるか?
  1. 2009年11月13日 05:36 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/1292-52cd55fe
この記事にトラックバックする(FC2ブログユーザー)