課題2


Sobelフィルタ

課題として、画像のエッジ抽出を行うsobelフィルタの処理回路を設計していただきます。エッジ抽出とは、画像中の濃淡値の変化量が大きい部分を領域の境界(エッジ)として検出する処理を指します。さらにSobelフィルタを用いるとノイズの軽減も行うことができます。オペレータは以下のようになります。

入力画素
 i[0][0] i[0][1] i[0][2]
 i[1][0] i[1][1] i[1][2]
 i[2][0] i[2][1] i[2][2]
x軸方向のsobelフィルタオペレータ
 -1 0 1
 -2 0 2
 -1 0
 1
y軸方向のsobelフィルタオペレータ
 -1 -2
 -1
 0 0 0
 1 2 1

2つのオペレータのうち、どちらか1つを使用することで縦か横の単方向のエッジを検出できます。両方使用すると縦横2方向を検出することができ、通常はこちらの方法でエッジ抽出を行います。

一般的なエッジ抽出ではオペレータとの演算後に絶対値をとったものを計算結果とします。つまり、単方向では|(x またはy方向の演算)|、2方向では|(x方向の演算)| + |(y方向の演算)|の計算を行うことになります。

最後にその計算結果を正規化や2値化することで、エッジを画像の形で出力させます。

今回は、初めにx方向のみのエッジ抽出を行うsobelフィルタの演算回路を設計します。下図はその回路構成の一例で、この回路を各課題の手順に従い、operationモジュール(operation.v) に記述していくことで、演算回路を実装していただきます。


課題2.1

絶対値の演算回路(上図abs)を以下の手順に従って設計してください。

  1. サンプルプロジェクトのソースウィンドウ内で右クリックし、新規Verilog Moduleを作成してください(作成方法の詳細は前回の資料を参照)。
  2. 「11ビット絶対値演算回路」のソースコードを記述し、所定の箇所に絶対値を求めるソースを追加してください。
  3. 記述が終わったら、シミュレーションを行い動作確認してください。

ヒント

ハードウェアでは、負の値は2の補数で表現されています。例をいかに示します。

11’d(-1) = 11’b11111111111
11’d(-2) = 11’b11111111110

absモジュールの雛形を以下に示します。

// 11ビット絶対値演算回路
module abs #(
  parameter DATA_WIDTH = 11
)(
  input [DATA_WIDTH - 1: 0] in,
  output reg [DATA_WIDTH - 2: 0] out,
  input rst,
  input clk
);

always @(posedge clk) begin
  if(rst) begin
    out <= 0;

  end else begin
  ///////////////////////////////////////////////////////////////////
  // ここに絶対値を求めるコードを記述 //
  ///////////////////////////////////////////////////////////////////
  end
end
endmodule

課題2.2

2.1で作成したabsモジュールをoperationモジュールに接続してください。

absモジュールを接続するためには、operationモジュールに以下のような記述を追加します。

abs
// #( .DATA_WIDTH(/* パラメータ名 */ )
abs_0 (
  .in (/* [in]に結線するwire or reg */),

  .out (/* [out]に結線するwire */ ),
  .rst(rst),
  .clk(clk)
);
// outputに結線できるのはwireのみ

absモジュールがソースツリーに組み込まれたら完了です。

課題2.3

単方向(x方向のみ)のエッジ抽出を行うsobelフィルタの演算回路をoperation.vに上図のブロック図のとおりに記述し、設計してください。FPGAボードを使って実際の動作を確認してください。

ヒント1

例えば(a+b+c*d)-(e+f+g)を計算する場合、下記のように設計することができます。

// 設計1
reg1 <= a + b;    reg2 <= c * d;    
reg3 <= e + f;    reg4 <= g;
reg5 <= reg1 + reg2;                reg6 <= reg3 + reg4;
out <= reg5 - reg6;

// 設計2
out <= (a+b+c*d)-(e+f+g);

設計2のように大きな計算を1行で書いてしまうと、1クロックサイクルあたりの計算が増え、回路の最大動作周波数が小さくなる場合があります(最大動作周波数が25MHz以下である場合、FPGAボードを用いで動作させることができません)。どこまで大きな計算が1クロックサイクルで計算可能であるかは場合によるため、ISEがレポートする最大動作周波数を確認してください(Synthesize report内の最後のあたりに書かれています)。

計算を数段階に分ける場合は、タイミングのずれに気を付けてください。例えば、設計1でgをreg4を経由させず、reg6 <=reg3 + g;と記述するとタイミングがずれてしまいます。

回路を設計するときにブロック図を書くと、計算のタイミングでミスをしにくくなります。

ヒント2

入力のvalid(valid_in)と出力のvalid(valid_out)の関係が合うように設計してください。上位モジュールでは,valid_outが有効になった回数をカウントすることで,現在の座標を算出しています。

第1週で作成したqueueのような回路が必要になります。

課題2.4

2方向(x、y方向)のエッジを検出するsobelフィルタ演算回路を設計してください。