Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

Harris のコーナー検出アルゴリズムの HDL コード生成

この例では、Harris の手法を使用してコーナー メトリクスを計算する MATLAB® 設計からの HDL コードの生成方法を示します。

コーナー検出アルゴリズム

コーナーは、イメージの 2 つのエッジが交差するイメージ内のポイントです。コーナーは、イメージの回転、並進、発光に対してロバストです。コーナーには、イメージ情報の復元、イメージのレジストレーション、オブジェクトの追跡など、さまざまな用途に使用できる重要な特徴があります。

コーナー検出アルゴリズムは、コーナー メトリクスを使用してコーナーを識別します。このメトリクスは、特定のオブジェクトのコーナーにあるピクセルの尤度に対応します。コーナー メトリクスのピークでコーナーが識別されます。Computer Vision Toolbox のドキュメントのCorner Detection (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-2022 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_filterreduce_matrix をインスタンス化して入力イメージのコーナーの特徴を検出します。make_buffer_matrix_gh および make_buffer_matrix_gv の出力を入力として受け取ります。

コーナー検出 MATLAB テスト ベンチ

MATLAB テスト ベンチを確認します。

edit(testbench_name);
clear mlhdlc_corner_detection;
clear mlhdlc_sobel;

%   Copyright 2011-2022 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 Coder™ プロジェクトの作成

1. HDL Coder プロジェクトを作成します。

coder -hdlcoder -new mlhdlc_corner_detect_prj

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

3.[型の自動定義] をクリックして MATLAB 関数 mlhdlc_corner_detection.m の入力と出力の推奨される型を使用します。

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

固定小数点変換と HDL コード生成の実行

  1. [ワークフロー アドバイザー] ボタンをクリックして、ワークフロー アドバイザーを開始します。

  2. [HDL コード生成] タスクを右クリックして [選択したタスクまで実行] を選択します。

単一の HDL ファイル mlhdlc_corner_detection_fixpt.vhd が MATLAB 設計に対して生成されます。フィルター設計に対する生成された HDL コードを確認するには、コード生成ログのウィンドウでハイパーリンクをクリックします。

MATLAB 設計の関数ごとに HDL ファイルを生成する場合は、[HDL コード生成] タスクの [詳細設定] タブで [関数に対してインスタンス化可能なコードを生成] チェック ボックスを選択します。関数のインスタンス化可能なコードの生成も参照してください。