# 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:

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

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

### Test the MATLAB Algorithm

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

```mlhdlc_corner_detection_tb ```
```Warning: vision.LocalMaximaFinder will be removed in a future release. Use the houghpeaks and imregionalmax functions with equivalent functionality instead. Warning: vision.MarkerInserter will be removed in a future release. Use the insertMarker function with equivalent functionality instead. ```

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

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.