В этом примере показано, как генерировать код HDL из конструкции MATLAB ®, которая реализует алгоритм адаптивного медианного фильтра и генерирует код HDL.
Адаптивный медианный фильтр выполняет пространственную обработку для уменьшения шума в изображении. Фильтр сравнивает каждый пиксель изображения с окружающими пикселями. Если одно из значений пикселя значительно отличается от большинства окружающих пикселей, пиксель рассматривается как шум. Затем алгоритм фильтрации заменяет шумовой пиксель медианными значениями окружающих пикселей. Этот процесс повторяется до тех пор, пока все шумовые пиксели в изображении не будут удалены.
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 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, [ ] );
Во избежание ошибок во время выполнения смоделировать конструкцию с помощью испытательного стенда.
mlhdlc_median_filter_tb

Перед созданием кода HDL для проекта MATLAB скопируйте файлы проекта и тестового стенда в записываемую папку. Эти команды копируют файлы во временную папку.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_med_filt'];
Создайте временную папку и скопируйте файлы MATLAB.
cd(tempdir);
[~, ~, ~] = rmdir(mlhdlc_temp_dir, 's');
mkdir(mlhdlc_temp_dir);
cd(mlhdlc_temp_dir);
Копирование файлов во временный каталог.
copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_img_pattern_noisy.tif'), mlhdlc_temp_dir);
Для более быстрого моделирования испытательного стенда:
1. Создайте файл MEX с помощью Coder™ MATLAB. Помощник по рабочим процессам HDL автоматизирует эти шаги при выполнении моделирования конструкции с фиксированной точкой.
codegen -o mlhdlc_median_filter -args {zeros(9,1), 0} mlhdlc_median_filter
[~, tbn] = fileparts(testbench_name);2. Моделирование конструкции с помощью файла MEX. При запуске тестового стенда кодер HDL использует файл MEX и выполняет моделирование быстрее.
mlhdlc_median_filter_tb
3. Очистите файл MEX.
clear mex;
rmdir('codegen', 's');
delete(['mlhdlc_median_filter', '.', mexext]);1. Создайте проект кодера HDL:
coder -hdlcoder -new mlhdlc_med_filt_prj
2. Добавить файл mlhdlc_median_filter.m в качестве функции MATLAB и mlhdlc_median_filter_tb.m в качестве испытательного стенда MATLAB.
3. Щелкните Автоопределение типов (Autodefine types) и используйте рекомендуемые типы для входов и выходов функции MATLAB. mlhdlc_median_filter.

Более подробное руководство по созданию и заполнению проектов кодера MATLAB HDL см. в разделе Начало работы с MATLAB в Workflow-процессе HDL.
Нажмите кнопку Помощник по рабочим процессам, чтобы запустить помощник по рабочим процессам.
Щелкните правой кнопкой мыши задачу Создание кода HDL и выберите Выполнить для выбранной задачи.
Один файл HDL mlhdlc_median_filter_fixpt.vhd создается для проекта MATLAB. Чтобы проверить созданный код HDL для конструкции фильтра, щелкните гиперссылки в окне Журнал генерации кода (Code Generation Log).
Если требуется создать файл HDL для каждой функции в конструкции MATLAB, на вкладке Дополнительно (Advanced) задачи Создание кода HDL (HDL Code Generation) установите флажок Генерировать код экземпляра для функций (Generate instantable code for functions). См. также раздел Создание кода экземпляра для функций.
Чтобы очистить временную папку проекта, выполните следующие команды:
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_med_filt']; clear mex; cd (mlhdlc_demo_dir); rmdir(mlhdlc_temp_dir, 's');