このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
適応メディアン フィルターの HDL コード生成
この例では、適応メディアン フィルター アルゴリズムを実装して HDL コードを生成する MATLAB® 設計からの HDL コードの生成方法を示します。
適応フィルター MATLAB 設計
適応メディアン フィルターは、空間処理を実行してイメージのノイズを減らします。フィルターはイメージ内の各ピクセルを周囲にあるピクセルと比較します。いずれかのピクセル値が周囲にあるピクセルの大部分と大きく異なる場合、そのピクセルはノイズとして扱われます。フィルター アルゴリズムは、そのノイズ ピクセルを周囲にあるピクセルの中央値に置き換えます。イメージ内のすべてのノイズ ピクセルが取り除かれるまでこのプロセスが繰り返されます。
design_name = 'mlhdlc_median_filter'; testbench_name = 'mlhdlc_median_filter_tb';
MATLAB 設計を確認します。
edit(design_name);
%#codegen function [pixel_val, pixel_valid] = mlhdlc_median_filter(c_data, c_idx) % Copyright 2011-2019 The MathWorks, Inc. smax = 9; persistent window; if isempty(window) window = zeros(smax, smax); end cp = ceil(smax/2); % center pixel; w3 = -1:1; w5 = -2:2; w7 = -3:3; w9 = -4:4; r3 = cp + w3; % 3x3 window r5 = cp + w5; % 5x5 window r7 = cp + w7; % 7x7 window r9 = cp + w9; % 9x9 window d3x3 = window(r3, r3); d5x5 = window(r5, r5); d7x7 = window(r7, r7); d9x9 = window(r9, r9); center_pixel = window(cp, cp); % use 1D filter for 3x3 region outbuf = get_median_1d(d3x3(:)'); [min3, med3, max3] = getMinMaxMed_1d(outbuf); % use 2D filter for 5x5 region outbuf = get_median_2d(d5x5); [min5, med5, max5] = getMinMaxMed_2d(outbuf); % use 2D filter for 7x7 region outbuf = get_median_2d(d7x7); [min7, med7, max7] = getMinMaxMed_2d(outbuf); % use 2D filter for 9x9 region outbuf = get_median_2d(d9x9); [min9, med9, max9] = getMinMaxMed_2d(outbuf); pixel_val = get_new_pixel(min3, med3, max3, ... min5, med5, max5, ... min7, med7, max7, ... min9, med9, max9, ... center_pixel); % we need to wait until 9 cycles for the buffer to fill up % output is not valid every time we start from col1 for 9 cycles. persistent datavalid if isempty(datavalid) datavalid = false; end pixel_valid = datavalid; datavalid = (c_idx >= smax); % build the 9x9 buffer window(:,2:smax) = window(:,1:smax-1); window(:,1) = c_data; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [min, med, max] = getMinMaxMed_1d(inbuf) max = inbuf(1); med = inbuf(ceil(numel(inbuf)/2)); min = inbuf(numel(inbuf)); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [min, med, max] = getMinMaxMed_2d(inbuf) [nrows, ncols] = size(inbuf); max = inbuf(1, 1); med = inbuf(ceil(nrows/2), ceil(ncols/2)); min = inbuf(nrows, ncols); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function new_pixel = get_new_pixel(... min3, med3, max3, ... min5, med5, max5, ... min7, med7, max7, ... min9, med9, max9, ... center_data) if (med3 > min3 && med3 < max3) new_pixel = get_center_data(min3, med3, max3,center_data); elseif (med5 > min5 && med5 < max5) new_pixel = get_center_data(min5, med5, max5,center_data); elseif (med7 > min7 && med7 < max7) new_pixel = get_center_data(min7, med7, max7,center_data); elseif (med9 > min9 && med9 < max9) new_pixel = get_center_data(min9, med9, max9,center_data); else new_pixel = center_data; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [new_data] = get_center_data(min,med,max,center_data) if center_data <= min || center_data >= max new_data = med; else new_data = center_data; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % perform median 1d computation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function outbuf = get_median_1d(inbuf) numpixels = length(inbuf); tbuf = inbuf; for ii=coder.unroll(1:numpixels) if bitand(ii,uint32(1)) == 1 tbuf = compare_stage1(tbuf); else tbuf = compare_stage2(tbuf); end end outbuf = tbuf; end function outbuf = compare_stage1(inbuf) numpixels = length(inbuf); tbuf = compare_stage(inbuf(1:numpixels-1)); outbuf = [tbuf(:)' inbuf(numpixels)]; end function outbuf = compare_stage2(inbuf) numpixels = length(inbuf); tbuf = compare_stage(inbuf(2:numpixels)); outbuf = [inbuf(1) tbuf(:)']; end function [outbuf] = compare_stage(inbuf) step = 2; numpixels = length(inbuf); outbuf = inbuf; for ii=coder.unroll(1:step:numpixels) t = compare_pixels([inbuf(ii), inbuf(ii+1)]); outbuf(ii) = t(1); outbuf(ii+1) = t(2); end end function outbuf = compare_pixels(inbuf) if (inbuf(1) > inbuf(2)) outbuf = [inbuf(1), inbuf(2)]; else outbuf = [inbuf(2), inbuf(1)]; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % perform median 2d computation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function outbuf = get_median_2d(inbuf) outbuf = inbuf; [nrows, ncols] = size(inbuf); for ii=coder.unroll(1:ncols) colData = outbuf(:, ii)'; colDataOut = get_median_1d(colData)'; outbuf(:, ii) = colDataOut; end for ii=coder.unroll(1:nrows) rowData = outbuf(ii, :); rowDataOut = get_median_1d(rowData); outbuf(ii, :) = rowDataOut; end end
MATLAB 関数はモジュール化されていて、いくつかの関数を使用してイメージのノイズをフィルター処理します。
適応フィルター MATLAB テスト ベンチ
MATLAB テスト ベンチ mlhdlc_median_filter_tb
は、典型的な入力範囲を使用してフィルターの設計を実行します。
MATLAB テスト ベンチを確認します。
edit(testbench_name);
I = imread('mlhdlc_img_pattern_noisy.tif'); J = I; % Copyright 2011-2019 The MathWorks, Inc. smax = 9; [nrows, ncols] = size(I); ll = ceil(smax/2); ul = floor(smax/2); for ii=1:ncols-smax for jj=1:nrows-smax c_idx = ii; c_data = double(I(jj:jj+smax-1, ii)); [pixel_val, pixel_valid] = mlhdlc_median_filter(c_data, c_idx); if pixel_valid J(jj, ii) = pixel_val; end end end h = figure; set( h, 'Name', [ mfilename, '_plot' ] ); subplot( 1, 2, 1 ); imshow( I, [ ] ); subplot( 1, 2, 2 ); imshow( J, [ ] );
MATLAB アルゴリズムのテスト
実行時エラーを避けるために、テスト ベンチを使用して設計をシミュレートします。
mlhdlc_median_filter_tb
より高速なシミュレーションのための設計の高速化
テスト ベンチをより高速にシミュレートするには、次を行います。
1. MATLAB Coder™ を使用して MEX ファイルを作成します。これらの手順は、設計の固定小数点シミュレーションの実行時に HDL ワークフロー アドバイザーによって自動化されます。
codegen -o mlhdlc_median_filter -args {zeros(9,1), 0} mlhdlc_median_filter [~, tbn] = fileparts(testbench_name);
2.MEX ファイルを使用して設計をシミュレートします。テスト ベンチの実行時に、HDL Coder は MEX ファイルを使用してシミュレーションをより高速に実行します。
mlhdlc_median_filter_tb
3.MEX ファイルをクリーンアップします。
clear mex; rmdir('codegen', 's'); delete(['mlhdlc_median_filter', '.', mexext]);
HDL Coder プロジェクトの作成
1. 次のように HDL Coder プロジェクトを作成します。
coder -hdlcoder -new mlhdlc_med_filt_prj
2.mlhdlc_median_filter.m
ファイルを [MATLAB 関数] としてプロジェクトに追加し、mlhdlc_median_filter_tb.m
を [MATLAB テスト ベンチ] として追加します。
3.[型の自動定義] をクリックして MATLAB 関数 mlhdlc_median_filter
の入力と出力の推奨される型を使用します。
MATLAB HDL Coder プロジェクトの作成と入力に関する詳細なチュートリアルについては、MATLAB から HDL へのワークフロー入門を参照してください。
固定小数点変換と HDL コード生成の実行
[ワークフロー アドバイザー] ボタンをクリックして、ワークフロー アドバイザーを開始します。
[HDL コード生成] タスクを右クリックして [選択したタスクまで実行] を選択します。
単一の HDL ファイル mlhdlc_median_filter_fixpt.vhd
が MATLAB 設計に対して生成されます。フィルター設計に対する生成された HDL コードを確認するには、コード生成ログのウィンドウでハイパーリンクをクリックします。
MATLAB 設計の関数ごとに HDL ファイルを生成する場合は、[HDL コード生成] タスクの [詳細設定] タブで [関数に対してインスタンス化可能なコードを生成] チェック ボックスを選択します。関数のインスタンス化可能なコードの生成も参照してください。