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

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

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

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

Алгоритмы обнаружения углов идентифицируют углы с помощью угловой метрики. Эта метрика соответствует вероятности пикселей, расположенных в углу определенных объектов. Peaks угловой метрики идентифицируют углы. См. также раздел «Обнаружение углов» (Computer Vision Toolbox) в документации 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);
clear mlhdlc_corner_detection;
clear mlhdlc_sobel;

%   Copyright 2011-2019 The MathWorks, Inc.

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, скопируйте файлы дизайна и испытательного стенда в папку с возможностью записи. Эти команды копируют файлы во временную папку.

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.

Более полное руководство по созданию и заполнению проектов MATLAB HDL Coder см. в разделе «Начало работы с MATLAB в HDL».

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

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

  2. Щелкните правой кнопкой мыши Генерации HDL-кода задачу и выберите Запуск для выбранной задачи.

Один файл HDL mlhdlc_corner_detection_fixpt.vhd генерируется для проекта MATLAB. Чтобы изучить сгенерированный HDL-код для создания фильтра, щелкните гиперссылки в окне Генерации кода Журнала.

Если необходимо сгенерировать HDL- файла для каждой функции в проекте MATLAB, на вкладке Advanced Генерации HDL-кода задачи установите флажок Generate instantiable кода for functions. Смотрите также Сгенерируйте Instantiable Code для функций.

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

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

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');