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-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 functioncompute_harris_metric
.compute_harris_metric
detects the corner features in the input image by instantiating functionsgaussian_filter
andreduce_matrix
. The function takes outputs ofmake_buffer_matrix_gh
andmake_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; % Assuming 'padImage' is the image you're working with thresholdValue = 0.0005; % Adjust the threshold according to your needs % Apply threshold thresholdedImage = padImage > thresholdValue; % Now find local maxima on the thresholded image localMaximaMask = imregionalmax(thresholdedImage,8); % Extract the coordinates of the local maxima [row, col] = find(localMaximaMask); % Prepare Corners matrix for visualization Corners = [col, row]; % Combine X and Y coordinates into a Nx2 matrix Corners_int32 = int32(Corners); % Visualize corners on the original image ImageCornersMarked = insertMarker(image_in, Corners_int32, 'o', 'Size', 5, 'Color', 'white'); % 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); imagesc(ImageCornersMarked); % Use imagesc for displaying the image with markers 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 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
Click the Workflow Advisor button to start the Workflow Advisor.
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.