Генерация HDL-кода для алгоритма детектирования углов методом Харриса

В этом примере показано, как сгенерировать HDL-код из проекта MATLAB®, который вычисляет угловую метрику при помощи метода Харриса.

Угловой алгоритм обнаружения

Угол является точкой в изображении, где два ребра изображения пересекаются. Углы устойчивы к повороту изображения, переводу и illumintation. Углы содержат важные функции, которые можно использовать во многих приложениях, таких как восстановление данных изображения, регистрации изображений и объектного отслеживания.

Угловые алгоритмы обнаружения идентифицируют углы при помощи угловой метрики. Эта метрика соответствует вероятности пикселей, расположенных на углу определенных объектов. Peaks угловой метрики идентифицирует углы. См. также Угловое Обнаружение в документации Computer Vision Toolbox. Угловой алгоритм обнаружения:

1. Читает входное изображение.

Image_in = checkerboard(10);

2. Находит углы.

cornerDetector = detectHarrisFeatures(Image_in);

3. Отображает результаты.

[~,metric] = step(cornerDetector,image_in);
figure;
subplot(1,2,1);
imshow(image_in);
title('Original');
subplot(1,2,2);
imshow(imadjust(metric));
title('Corner metric');

Угловое обнаружение проект MATLAB

design_name = 'mlhdlc_corner_detection';
testbench_name = 'mlhdlc_corner_detection_tb';

Рассмотрите проект MATLAB:

edit(design_name);
%#codegen
function [valid, ed, xfo, yfo, cm] = mlhdlc_corner_detection(data_in)
%   Copyright 2011-2019 The MathWorks, Inc.

[~, ed, xfo, yfo] = mlhdlc_sobel(data_in);

cm = compute_corner_metric(xfo, yfo);

% compute valid signal
persistent cnt
if isempty(cnt)
  cnt = 0;
end
cnt = cnt + 1;
valid = cnt > 3*80+3 && cnt <= 80*80+3*80+3;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bm = compute_corner_metric(gh, gv)

cmh = make_buffer_matrix_gh(gh);
cmv = make_buffer_matrix_gv(gv);
bm = compute_harris_metric(cmh, cmv);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bm = make_buffer_matrix_gh(gh)

persistent b1 b2 b3 b4;
if isempty(b1)
    b1 = dsp.Delay('Length', 80);
    b2 = dsp.Delay('Length', 80);
    b3 = dsp.Delay('Length', 80);
    b4 = dsp.Delay('Length', 80);
end

b1p = step(b1, gh);
b2p = step(b2, b1p);
b3p = step(b3, b2p);
b4p = step(b4, b3p);

cc = [b4p b3p b2p b1p gh];

persistent h1 h2 h3 h4;
if isempty(h1)
    h1 = dsp.Delay();
    h2 = dsp.Delay();
    h3 = dsp.Delay();
    h4 = dsp.Delay();
end

h1p = step(h1, cc);
h2p = step(h2, h1p);
h3p = step(h3, h2p);
h4p = step(h4, h3p);

bm = [h4p h3p h2p h1p cc];

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function bm = make_buffer_matrix_gv(gv)

persistent b1 b2 b3 b4;
if isempty(b1)
    b1 = dsp.Delay('Length', 80);
    b2 = dsp.Delay('Length', 80);
    b3 = dsp.Delay('Length', 80);
    b4 = dsp.Delay('Length', 80);
end

b1p = step(b1, gv);
b2p = step(b2, b1p);
b3p = step(b3, b2p);
b4p = step(b4, b3p);

cc = [b4p b3p b2p b1p gv];

persistent h1 h2 h3 h4;
if isempty(h1)
    h1 = dsp.Delay();
    h2 = dsp.Delay();
    h3 = dsp.Delay();
    h4 = dsp.Delay();
end

h1p = step(h1, cc);
h2p = step(h2, h1p);
h3p = step(h3, h2p);
h4p = step(h4, h3p);

bm = [h4p h3p h2p h1p cc];

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cm = compute_harris_metric(gh, gv)

[g1, g2, g3] = gaussian_filter(gh, gv);
[s1, s2, s3] = reduce_matrix(g1, g2, g3);

cm = (((s1*s3) - (s2*s2)) - (((s1+s3) * (s1+s3)) * 0.04));

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [g1, g2, g3] = gaussian_filter(gh, gv)

%g=fspecial('gaussian',[5 5],1.5);
g = [0.0144    0.0281    0.0351    0.0281    0.0144
     0.0281    0.0547    0.0683    0.0547    0.0281
     0.0351    0.0683    0.0853    0.0683    0.0351
     0.0281    0.0547    0.0683    0.0547    0.0281
     0.0144    0.0281    0.0351    0.0281    0.0144];

g1 = (gh .* gh) .* g(:)';
g2 = (gh .* gv) .* g(:)';
g3 = (gv .* gv) .* g(:)';

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [s1, s2, s3] = reduce_matrix(g1, g2, g3)

s1 = sum(g1);
s2 = sum(g2);
s3 = sum(g3);

end


Функция MATLAB является модульной и использует несколько функций, чтобы вычислить углы изображения. Функция:

  • compute_corner_metric вычисляет угловую метрическую матрицу путем инстанцирования функционального compute_harris_metric.

  • compute_harris_metric обнаруживает угловые функции во входном изображении путем инстанцирования функций gaussian_filter и reduce_matrix. Функция берет выходные параметры make_buffer_matrix_gh и make_buffer_matrix_gv как входные параметры.

Угловое обнаружение испытательный стенд MATLAB

Рассмотрите испытательный стенд MATLAB:

edit(testbench_name);
%   Copyright 2011-2019 The MathWorks, Inc.
clear mlhdlc_corner_detection;
clear mlhdlc_sobel;

image_in = checkerboard(10);
[image_height, image_width] = size(image_in);

% Pre-allocating y for simulation performance
y_cm = zeros(image_height, image_width);
y_ed = zeros(image_height, image_width);
gradient_hori = zeros(image_height,image_width);
gradient_vert = zeros(image_height,image_width);

dataValidOut = y_cm;

idx_in = 1;
idx_out = 1;
for i=1:image_width+3
    for j=1:image_height+3
        if idx_in <= image_width * image_height
            u = image_in(idx_in);
        else
            u = 0;
        end
        idx_in = idx_in + 1;
        
        [valid, ed, gh, gv, cm] = mlhdlc_corner_detection(u);
        
        if valid
            
            y_cm(idx_out) = cm;
            y_ed(idx_out) = ed;
            gradient_hori(idx_out)   = gh;
            gradient_vert(idx_out)   = gv;
            
            idx_out = idx_out + 1;
        end
    end
end

padImage = y_cm;
findLocalMaxima = vision.LocalMaximaFinder('MaximumNumLocalMaxima',100, ...
    'NeighborhoodSize', [11 11], ...
    'Threshold', 0.0005);
Corners = step(findLocalMaxima, padImage);
drawMarkers = vision.MarkerInserter('Size', 2); % Draw circles at corners
ImageCornersMarked = step(drawMarkers, image_in, Corners);

% Display results
% ...
%

nplots = 4;

scrsz = get(0,'ScreenSize');
figure('Name', [mfilename, '_plot'], 'Position',[1 300 700 200])

subplot(1,nplots,1);
imshow(image_in,[min(image_in(:)) max(image_in(:))]);
title('Checker Board')
axis square

subplot(1,nplots,2);
imshow(gradient_hori(3:end,3:end),[min(gradient_hori(:)) max(gradient_hori(:))]);
title(['Vertical',newline,' Gradient'])
axis square

subplot(1,nplots,3);
imshow(gradient_vert(3:end,3:end),[min(gradient_vert(:)) max(gradient_vert(:))]);
title(['Horizontal',newline,' Gradient'])
axis square

% subplot(1,nplots,4);
% imshow(y_ed);
% title('Edges')

subplot(1,nplots,4);
imagesc(ImageCornersMarked)
title('Corners');
axis square

Протестируйте алгоритм MATLAB

Чтобы избежать ошибок времени выполнения, симулируйте проект с испытательным стендом.

mlhdlc_corner_detection_tb

Создайте папку и скопируйте соответствующие файлы

Прежде чем вы сгенерируете HDL-код для проекта MATLAB, скопируете проект и файлы испытательного стенда к writeable папке. Эти команды копируют файлы во временную папку.

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_cdetect'];

Создайте временную папку и скопируйте файлы 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_sobel.m*'), mlhdlc_temp_dir);

Создайте проект HDL Coder™

1. Создайте проект HDL Coder:

coder -hdlcoder -new mlhdlc_corner_detect_prj

2. Добавьте файл mlhdlc_corner_detection.m к проекту как функция MATLAB и mlhdlc_corner_detection_tb.m как испытательный стенд MATLAB.

3. Нажмите типы Autodefine, чтобы использовать рекомендуемые типы во вводах и выводах функции MATLAB mlhdlc_corner_detection.m.

Чтобы узнать больше, как создать и заполнить проект HDL Coder, смотрите Начало работы с MATLAB к Рабочему процессу HDL.

Запустите преобразование фиксированной точки и генерацию HDL-кода

  1. Нажмите кнопку Workflow Advisor, чтобы запустить Советника по вопросам Рабочего процесса.

  2. Щелкните правой кнопкой мыши по задаче генерации HDL-кода и выберите Run к выбранной задаче.

Один файл HDL mlhdlc_corner_detection_fixpt.vhd сгенерирован для проекта MATLAB. Чтобы исследовать сгенерированный HDL-код на создание фильтра, кликните по гиперссылкам в окне Code Generation Log.

Если вы хотите сгенерировать файл HDL для каждой функции в вашем проекте MATLAB во Вкладке "Дополнительно" задачи генерации HDL-кода, выберите Generate instantiable код для флажка функций. См. также Генерируют Код Instantiable для Функций.

Очистите сгенерированные файлы

Чтобы очистить временную папку проекта, запустите эти команды:

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_cdetect'];
clear mex;
cd (mlhdlc_demo_dir);
rmdir(mlhdlc_temp_dir, 's');