Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

イメージをシャープ化する HDL コードの生成

この例は、イメージをシャープ化する FPGA ベースのモジュールを、Vision HDL Toolbox™ を使用して実装する方法を示します。

Vision HDL Toolbox には、読みやすく合成可能な VHDL コードや Verilog コードを HDL Coder™ で生成できるように設計されたイメージ処理および動画処理のアルゴリズムが備わっています。生成された HDL コードを FPGA (たとえば、Xilinx XC7Z045 など) で実行すると、60 フレーム/秒で 1920 x 1080 の高解像度イメージを処理できます。

この例は、Vision HDL Toolbox を使用して、ブレを含むイメージをシャープ化する HDL コードの生成方法を示します。Vision HDL Toolbox アルゴリズムは MATLAB® System objects™ や Simulink® ブロックとして使用できるため、MATLAB または Simulink から HDL コードを生成できます。この例では両方のワークフローを示します。

FPGA ターゲット設計のワークフロー:

1.設計目標を表す動作モデルを作成します。

2.FPGA に適しており、かつ HDL コード生成でサポートされているアルゴリズム、インターフェイス、データ型を使用して設計を再現します。

3.2 つの設計をシミュレートし、その結果を比較して、目標に沿った HDL 最適化設計であることを確認します。

4.手順 2 で作成した設計から HDL コードを生成します。

MATLAB の場合、手順 2 および 3 で MATLAB、Vision HDL Toolbox、Fixed-Point Designer™ が必要です。Simulink の場合、Simulink、Vision HDL Toolbox、Fixed-Point Designer が必要です。いずれの場合も、HDL コードの生成には HDL Coder が必要になります。

動作モデル

次の図の左側に入力イメージ imgBlur を示します。右側には、Image Processing Toolbox™ 関数 imfilter を使用してシャープにしたイメージがあります。

後で比較するときのベンチマークとしてシミュレーション時間が表示されます。

imgBlur = imread('riceblurred.png');
sharpCoeff = [0 0 0;0 1 0;0 0 0]-fspecial('laplacian',0.2);

f = @() imfilter(imgBlur,sharpCoeff,'symmetric');
fprintf('Elapsed time is %.6f seconds.\n',timeit(f));

imgSharp = imfilter(imgBlur,sharpCoeff,'symmetric');
figure
imshowpair(imgBlur,imgSharp,'montage')
title('Blurred Image and Sharpened Image')
Elapsed time is 0.000606 seconds.

HDL 最適化設計の注意事項

HDL コードを生成できるようにするには、3 つの重要な変更が必要になります。

  • HDL フレンドリなアルゴリズムの使用: Image Processing Toolbox の関数は HDL コード生成をサポートしていません。HDL の効率的な実装のために設計されたイメージ処理および動画処理のアルゴリズムが Vision HDL Toolbox で提供されています。Functions (Vision HDL Toolbox)Blocks (Vision HDL Toolbox) を使用して、これらのアルゴリズムから HDL コードを生成できます。この例では両方のワークフローを示します。FPGA ベースのモジュールを設計するには、Image Processing Toolbox の関数を、それに対応する Vision HDL Toolbox の HDL フレンドリな同等の機能に置き換えます。この例では、動作モデルの imfilter を、MATLAB の visionhdl.ImageFilter System object または Simulink の Image Filter ブロックに置き換えています。

  • ストリーミング ピクセル インターフェイスの使用: Image Processing Toolbox の関数は高度に抽象化されたモデルを作成します。これらの関数はイメージ フレームを 1 個ずつフル フレームで処理します。一方、FPGA や ASIC の実装では、イメージ ピクセルを 1 つずつ処理するピクセル ストリーム処理が行われます。Vision HDL Toolbox のブロックと System object ではストリーミング ピクセル インターフェイスを使用します。フル フレームのイメージやビデオをピクセル ストリームに変換するには、MATLAB の visionhdl.FrameToPixels System object または Simulink の Frame To Pixels ブロックを使用します。ストリーミング ピクセル インターフェイスには、フレーム内での各ピクセルの位置を示す制御信号が含まれています。ピクセルの近傍を処理するアルゴリズムでは内部メモリを使用して最小数のラインを格納します。Vision HDL Toolbox はストリーミング ピクセル インターフェイスと自動メモリ実装を備えており、FPGA や ASIC をターゲットにするときの一般的な設計問題に対応します。Vision HDL Toolbox の System object で使用されるストリーミング ピクセル プロトコルの詳細については、Streaming Pixel Interface (Vision HDL Toolbox)を参照してください。

  • 固定小数点データ表現の使用: Image Processing Toolbox の関数は浮動小数点領域または整数領域で動画処理アルゴリズムを実行します。Vision HDL Toolbox の System object およびブロックで FPGA や ASIC をターゲットにする HDL コードを生成するためには、固定小数点データにする必要があります。設計を固定小数点に変換すると、量子化誤差が発生する可能性があります。そのため、HDL フレンドリなモデルで生成される出力は、動作モデルから得られる出力と若干異なる場合もあります。ほとんどの場合、許容誤差内の小さい量子化誤差は問題となりません。要件に応じて固定小数点設定を調整することができます。

この例では、静的イメージをソースとして使用します。また、このモデルは連続したビデオ入力を処理することもできます。

MATLAB からの HDL コードの生成

MATLAB から HDL を生成するには、コードをテスト ベンチと設計の 2 つのファイルに分割する必要があります。設計ファイルはアルゴリズムを FPGA または ASIC に実装する場合に使用します。テスト ベンチ ファイルは入力データを設計ファイルに与え、設計の出力を受け取ります。

手順 1: 設計ファイルの作成

関数 ImageSharpeningHDLDesign.m はピクセル ストリームと、5 つの制御信号から構成される制御構造体を受け入れ、変更後のピクセル ストリームと制御構造体を返します。

この例では、visionhdl.ImageFilter System object が設計に含まれています。これは関数 imfilter に対応する、HDL フレンドリな同等の機能です。imfilter と同じ係数およびパディング方法を使用して設定します。

function [pixOut,ctrlOut] = ImageSharpeningHDLDesign(pixIn,ctrlIn)
% ImageSharpeningHDLDesign  Implement algorithms using pixel-stream 
%       System objects from the Vision HDL Toolbox

%   Copyright 2015-2022 The MathWorks, Inc.

%#codegen
persistent sharpeningFilter;
if isempty(sharpeningFilter)   
    sharpCoeff = [0 0 0;0 1 0;0 0 0]-fspecial('laplacian',0.2);
    sharpeningFilter = visionhdl.ImageFilter(...
    'Coefficients',sharpCoeff,...
    'PaddingMethod','Symmetric',...
    'CoefficientsDataType','Custom',...
    'CustomCoefficientsDataType',numerictype(1,16,12));              
end

[pixOut,ctrlOut] = sharpeningFilter(pixIn,ctrlIn);


手順 2: テスト ベンチ ファイルの作成

テスト ベンチ ImageSharpeningHDLTestBench でブレを含むイメージを読み取ります。frm2pix オブジェクトでフル イメージ フレームをピクセル ストリームと制御構造体に変換します。テスト ベンチにより、ピクセルを 1 つずつ処理する設計関数 ImageSharpeningHDLDesign が呼び出されます。ピクセル ストリーム全体が処理されたら、pix2frm で出力ピクセル ストリームをフル フレーム イメージに変換します。テスト ベンチは出力イメージを参照出力 imgSharp と比較します。

...
[pixInVec,ctrlInVec] = frm2pix(imgBlur);
for p = 1:numPixPerFrm
    [pixOutVec(p),ctrlOutVec(p)] = ImageSharpeningHDLDesign(pixInVec(p),ctrlInVec(p));
end
imgOut = pix2frm(pixOutVec,ctrlOutVec);
% Compare the result
imgDiff = imabsdiff(imgSharp,imgOut);
fprintf('The maximum difference between corresponding pixels is %d.\n',max(imgDiff(:)));
fprintf('A total of %d pixels are different.\n',nnz(imgDiff));
...

手順 3: 設計のシミュレーションおよび結果の確認

HDL コードの生成前にテスト ベンチを使用して設計をシミュレートし、実行時エラーが発生しないことを確認します。

ImageSharpeningHDLTestBench
The maximum difference between corresponding pixels is 1.
A total of 41248 pixels are different.

Simulation took 664.096485 seconds to finish.

テスト ベンチは比較結果とシミュレーションに要した時間を表示します。量子化誤差および丸め誤差により、合計 256*256=65536 ピクセルのうち imgOut の 38554 ピクセルが imgSharp と異なっています。一方、強度の最大の差は 1 です。0 から 255 のスケール上では、視認できないほどの差です。

MATLAB と動作モデルのシミュレーション時間を比較するとわかるように、ピクセル ストリーミング プロトコルが多大なオーバーヘッドをもたらしています。MATLAB Coder™ を使用すると、MATLAB でのピクセル ストリーミング シミュレーションを高速化できます。Accelerate Pixel-Streaming Designs Using MATLAB Coder (Vision HDL Toolbox)を参照してください。

手順 4: HDL コードの生成

FPGA ターゲット モデルで満足な結果が得られたら、HDL Coder を使用して設計から HDL コードを生成することができます。生成された HDL コードは、HDL シミュレーターで実行したり、FPGA に読み込んで物理システムで実行することができます。

設計ファイルとテスト ベンチ ファイルが同一の書き込み可能なディレクトリにあることを確認してください。HDL コードを生成するには、次のコマンドを使用します。

hdlcfg = coder.config('hdl');
hdlcfg.TestBenchName = 'ImageSharpeningHDLTestBench';
hdlcfg.TargetLanguage = 'Verilog';
hdlcfg.GenerateHDLTestBench = false;
codegen -config hdlcfg ImageSharpeningHDLDesign

HDL プロジェクトの作成と MATLAB の設定に関する詳細については、HDL Coder ドキュメンテーションの「Getting Started with MATLAB to HDL Workflow」チュートリアルを参照してください。

Simulink からの HDL コードの生成

手順 1: HDL 最適化モデルの作成

ImageSharpeningHDLModel モデルを以下に示します。

modelname = 'ImageSharpeningHDLModel';
open_system(modelname);
set_param(modelname,'Open','on');

ブレを含むイメージをこのモデルで読み取ります。Frame To Pixels ブロックでフル フレーム イメージをピクセル ストリームに変換し、Pixels To Frame ブロックでピクセル ストリームを元のフル フレーム イメージに変換します。Image Sharpening HDL System に含まれている Image Filter ブロックは、動作モデル内の関数 imfilter に対応する HDL フレンドリな Vision HDL Toolbox のブロックです。

set_param(modelname,'Open','off');
set_param([modelname '/Image Sharpening HDL System'],'Open','on');

以下のマスクで示すように、Image Filter ブロックは動作モデルと同じシャープ化係数およびパディング方法を使用して設定します。

手順 2: 設計のシミュレーションおよび結果の確認

tic
sim(modelname);
toc
Elapsed time is 16.774461 seconds.

Simulink では C コード生成を利用してシミュレーションを高速化します。そのため、動作モデルには劣るものの MATLAB シミュレーションよりはるかに高速です。

シミュレーションでは、imgOut という名前の新しい変数がワークスペースに作成されます。次のコマンドを使用して imgOut を、動作モデルから生成された imSharp と比較します。

imgDiff = imabsdiff(imgSharp,imgOut);
fprintf('The maximum difference between corresponding pixels is %d.\n',max(imgDiff(:)));
fprintf('A total of %d pixels are different.\n',nnz(imgDiff));
The maximum difference between corresponding pixels is 1.
A total of 41248 pixels are different.

量子化誤差および丸め誤差により、合計 256*256=65536 ピクセルのうち imgOut の 41248 ピクセルが imgSharp と異なっています。一方、強度の最大の差は 1 です。0 から 255 のスケール上では、視認できないほどの差です。(この理論は、「MATLAB からの HDL コードの生成」の手順 3 にも示されています。)

手順 3: HDL コードの生成

FPGA ターゲット モデルで満足な結果が得られたら、HDL Coder を使用して設計から HDL コードを生成することができます。生成された HDL コードは、HDL シミュレーターで実行したり、FPGA に読み込んで物理システムで実行することができます。

次のコマンドを使用して Image Sharpening HDL System から HDL コードを生成します。

makehdl('ImageSharpeningHDLModel/Image Sharpening HDL System')
set_param([modelname '/Image Sharpening HDL System'],'Open','off');
close_system(modelname,0);
close all;