Main Content

ノイズを含むカラー ビデオの拡張エッジ検出

この例では、複雑なピクセルストリーム動画処理アルゴリズムを開発し、そのシミュレーションを MATLAB® Coder™ を使用して高速化し、設計から HDL コードを生成する方法を示します。このアルゴリズムでは、ノイズを含むカラー ビデオからのエッジ検出を拡張します。

この例を実行するには、MATLAB Coder のライセンスが必要です。

この例は、Pixel-Streaming Design in MATLAB (Vision HDL Toolbox)およびAccelerate Pixel-Streaming Designs Using MATLAB Coder (Vision HDL Toolbox)の例を基にしています。

テスト ベンチ

EnhancedEdgeDetectionHDLTestBench.m ファイルでは、"videoIn" オブジェクトでカラー ビデオ ソースから各フレームを読み取り、関数 imnoise でごま塩ノイズを追加します。このノイズを含むカラー イメージが "frm2pix" オブジェクトに渡され、完全なイメージ フレームがピクセルと制御構造のストリームに変換されます。その後、関数 EnhancedEdgeDetectionHDLDesign.m が呼び出され、ピクセル (およびそれに関連付けられた制御構造) が一度に 1 つずつ処理されます。ピクセルストリーム全体の処理が完了して出力ストリームを収集すると、pix2frm オブジェクトが出力ストリームをフルフレームのビデオに変換します。さらに、フルフレームのリファレンス設計 EnhancedEdgeDetectionHDLReference.m が呼び出され、ノイズを含むカラー イメージが処理されます。その出力がピクセルストリームの設計の出力と比較されます。関数 EnhancedEdgeDetectionHDLViewer.m が呼び出されて、ビデオ出力が表示されます。

上記のワークフローは、EnhancedEdgeDetectionHDLTestBench.m の次の行で実装されます。

...
frmIn = zeros(actLine,actPixPerLine,3,'uint8');       
for f = 1:numFrm           
    frmFull = readFrame(videoIn);             % Get a new frame    
    frmIn = imnoise(frmFull,'salt & pepper'); % Add noise        
     % Call the pixel-stream design
     [pixInVec,ctrlInVec] = frm2pix(frmIn);       
     for p = 1:numPixPerFrm    
         [pixOutVec(p),ctrlOutVec(p)] = EnhancedEdgeDetectionHDLDesign(pixInVec(p,:),ctrlInVec(p));                                  
     end        
     frmOut = pix2frm(pixOutVec,ctrlOutVec);    
     % Call the full-frame reference design
     [frmGray,frmDenoise,frmEdge,frmRef] = EnhancedEdgeDetectionHDLReference(frmIn);
     % Compare the results
     if nnz(imabsdiff(frmRef,frmOut))>20
         fprintf('frame %d: reference and design output differ in more than 20 pixels.\n',f);
         return;
     end 
     % Display the results
     EnhancedEdgeDetectionHDLViewer(actPixPerLine,actLine,[frmGray frmDenoise uint8(255*[frmEdge frmOut])],[frmFull frmIn]);
 end
 ...

frmGray と frmDenoise のデータ型は uint8 であるのに対し、frmEdge と frmOut は logical であるため、行列を連結できるように、"uint8(255x[frmEdge frmOut])" で logical の false と true を uint8(0) と uint8(255) にそれぞれマッピングしています。

フルフレームとピクセルストリームの領域間の変換には、frm2pixpix2frm の両方が使用されます。内側の for ループは、ピクセルストリームの処理を実行します。テスト ベンチの残りの部分は、フルフレームの処理を実行します。

テスト ベンチが終了する前に、シミュレーション速度を示すフレーム レートが表示されます。

この例の関数のうち、C コード生成をサポートしていない tictocimnoisefprintf などについては、"coder.extrinsic" を使用して外部関数として宣言します。外部関数は MEX の生成から除外されます。シミュレーションでは、それらを通常のインタープリター型モードで実行します。imnoise については、C コード生成プロセスに含まれないため、コンパイラで frmIn のデータ型とサイズを推定できません。この欠けている部分を埋めるために、外側の for ループの前にステートメント "frmIn = zeros(actLine,actPixPerLine,3,'uint8')" を追加しています。

ピクセルストリームの設計

EnhancedEdgeDetectionHDLDesign.m で定義されている関数は、ピクセル ストリームと 5 つの制御信号から成る構造体を受け入れ、変更されたピクセル ストリームと制御構造を返します。Vision HDL Toolbox の System object で使用されるストリーミング ピクセル プロトコルの詳細については、Streaming Pixel Interface (Vision HDL Toolbox)を参照してください。

この例では、"rgb2gray" オブジェクトでカラー イメージをグレースケールに変換し、"medfil" でごま塩ノイズを除去します。"sobel" はエッジを強調表示します。最後に、"mclose" オブジェクトでモルフォロジー クロージングを実行してエッジの出力を拡張します。コードは次のとおりです。

[pixGray,ctrlGray] = rgb2gray(pixIn,ctrlIn);         % Convert RGB to grayscale
[pixDenoise,ctrlDenoise] = medfil(pixGray,ctrlGray); % Remove noise
[pixEdge,ctrlEdge] = sobel(pixDenoise,ctrlDenoise);  % Detect edges
[pixClose,ctrlClose] = mclose(pixEdge,ctrlEdge);     % Apply closing

フルフレームのリファレンス設計

複雑なピクセルストリーム動画処理アルゴリズムを設計するときは、Image Processing Toolbox™ の関数を使用して対応するリファレンス設計を開発することをお勧めします。それらの関数で完全なイメージ フレームを処理します。このようなリファレンス設計は、フルフレームのリファレンス設計の出力イメージをピクセルストリームの設計の出力と比較して、ピクセルストリームの設計の実装を検証するのに役立ちます。

関数 EnhancedEdgeDetectionHDLReference.m には、EnhancedEdgeDetectionHDLDesign.m の 4 つの関数と同様の一連の関数が含まれています。主な違いは、Image Processing Toolbox の関数はフルフレームのデータを処理することです。

関数 edgevisionhdl.EdgeDetector System object の実装の違いにより、リファレンスと設計の出力は frmOut と frmRef の差が 20 ピクセル以下であれば一致すると見なされます。

MEX ファイルの作成と設計のシミュレーション

MEX ファイルを生成して実行します。

codegen('EnhancedEdgeDetectionHDLTestBench');
Code generation successful.
EnhancedEdgeDetectionHDLTestBench_mex;
frame 1: reference and design output differ in more than 20 pixels.

上のビデオ プレーヤーは、元のカラー ビデオを左に、ごま塩ノイズを追加した後のノイズを含むバージョンを右に表示しています。下のビデオ プレーヤーは、左から右の順に、色空間変換後のグレースケール イメージ、メディアン フィルター後のノイズ除去したバージョン、エッジ検出後のエッジの出力、モルフォロジー クロージング演算後の拡張されたエッジの出力を表しています。

下の一連のビデオのうち、ピクセルストリームの設計から生成されたものは拡張されたエッジの出力 (一番右のビデオ) だけであることに注意してください。他の 3 つはフルフレームのリファレンス設計からの途中のビデオです。4 つすべてのビデオをピクセルフレームの設計から表示するには、設計ファイルで 4 組のピクセルと制御信号を出力するように記述し、"visionhdl.PixelsToFrame" オブジェクトをあと 3 つインスタンス化して、途中の 3 つのピクセル ストリームをフレームに変換し直しておきます。この例では、シミュレーションの速度とコードのわかりやすさを考慮し、途中のピクセルストリームの表示は実装していません。

HDL コード生成

新しいプロジェクトを作成するには、一時フォルダーで次のコマンドを入力します。

coder -hdlcoder -new EnhancedEdgeDetectionProject

次に、'EnhancedEdgeDetectionHDLDesign.m' ファイルを [MATLAB 関数] としてプロジェクトに追加し、'EnhancedEdgeDetectionHDLTestBench.m' を [MATLAB テスト ベンチ] として追加します。

MATLAB HDL Coder プロジェクトの作成と入力に関するチュートリアルについては、MATLAB から HDL へのワークフロー入門を参照してください。

ワークフロー アドバイザーを起動します。ワークフロー アドバイザーで、[コード生成] の手順を右クリックします。[選択したタスクまで実行] オプションを選択して、最初から HDL コード生成までのすべての手順を実行します。

ログ ウィンドウにあるリンクをクリックして、生成された HDL コードを確認します。