# HDL Code Generation for Harris Corner Detection Algorithm

This example shows how to generate HDL code from a MATLAB® design that computes the corner metric by using Harris' technique.

### Corner Detection Algorithm

A corner is a point in an image where two edges of the image intersect. The corners are robust to image rotation, translation, and illumination. Corners contain important features that you can use in many applications such as restoring image information, image registration, and object tracking.

Corner detection algorithms identify the corners by using a corner metric. This metric corresponds to the likelihood of pixels located at the corner of certain objects. Peaks of corner metric identify the corners. See also Corner Detection (Computer Vision Toolbox) in the Computer Vision Toolbox documentation. The corner detection algorithm:

1. Reads the input image.

```Image_in = checkerboard(10); ```

2. Finds the corners.

```cornerDetector = detectHarrisFeatures(Image_in); ```

3. Displays the results.

```[~,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'); ```

### Corner Detection MATLAB Design

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

Review the MATLAB design:

```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 ```

The MATLAB function is modular and uses several functions to compute the corners of the image. The function:

• `compute_corner_metric` computes the corner metric matrix by instantiating the function `compute_harris_metric`.

• `compute_harris_metric` detects the corner features in the input image by instantiating functions `gaussian_filter` and `reduce_matrix`. The function takes outputs of `make_buffer_matrix_gh` and `make_buffer_matrix_gv` as the inputs.

### Corner Detection MATLAB Test Bench

Review the MATLAB test bench:

```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 ```

### Test the MATLAB Algorithm

To avoid run-time errors, simulate the design with the test bench.

```mlhdlc_corner_detection_tb ```

### Create a Folder and Copy Relevant Files

Before you generate HDL code for the MATLAB design, copy the design and test bench files to a writeable folder. These commands copy the files to a temporary folder.

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

Create a temporary folder and copy the MATLAB files.

```cd(tempdir); [~, ~, ~] = rmdir(mlhdlc_temp_dir, 's'); mkdir(mlhdlc_temp_dir); cd(mlhdlc_temp_dir); ```

Copy the design files to the temporary directory.

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

### Create an HDL Coder™ Project

1. Create a HDL Coder project:

```coder -hdlcoder -new mlhdlc_corner_detect_prj ```

2. Add the file `mlhdlc_corner_detection.m` to the project as the MATLAB Function and `mlhdlc_corner_detection_tb.m` as the MATLAB Test Bench.

3. Click Autodefine types to use the recommended types for the inputs and outputs of the MATLAB function `mlhdlc_corner_detection.m`.

Refer to Get Started with MATLAB to HDL Workflow for a more complete tutorial on creating and populating MATLAB HDL Coder projects.

### Run Fixed-Point Conversion and HDL Code Generation

1. Click the Workflow Advisor button to start the Workflow Advisor.

2. Right click the HDL Code Generation task and select Run to selected task.

A single HDL file `mlhdlc_corner_detection_fixpt.vhd` is generated for the MATLAB design. To examine the generated HDL code for the filter design, click the hyperlinks in the Code Generation Log window.

If you want to generate a HDL file for each function in your MATLAB design, in the Advanced tab of the HDL Code Generation task, select the Generate instantiable code for functions check box. See also Generate Instantiable Code for Functions.

### Clean Up Generated Files

To clean up the temporary project folder, run these commands:

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