Compute Image Characteristics with a Frame-Based Model for HDL Code Generation
In this example, you use frame-based modeling to model an image processing algorithm that detects an object based on color. The model takes 2-D images as input and produces a two-element location for the detected object. You then generate synthesizable HDL code by using the HDL Coder™ frame-to-sample conversion optimization, which generates pixel-based code from a frame-based model. For more info on the frame-to-sample conversion optimization, see HDL Code Generation from Frame-Based Algorithms.
The object detection model uses neighborhood, iterator, and element-wise operator patterns. You can model neighborhood patterns by using the hdl.npufun
function in a MATLAB® Function block or the Neighborhood Processing Subsystem block. You can implement iterator patterns by using hdl.iteratorfun
in a MATLAB Function block. You can model element-wise operations using Simulink® blocks. Neighborhood processing operations, element-wise operations using Simulink blocks, and iterator operations support the generation of synthesizable HDL code by using the frame-to-sample conversion optimization. This model uses Sum, Abs, Relational, and Logical Operator blocks for element-wise operations. The input to the model is a frame-based RGB video signal. The output from the model is the sample-based location of the detected object.
Inspect and Run the Model
In the hdlFrame_ObjectDetecting
model, the device under test (DUT) contains a MATLAB Function block rgb2hsv
that uses neighborhood processing to convert the input RGB color space to the HSV color space. The HSV color space output is passed into the FindTarget
subsystem that contains Simulink blocks that detect the target color area. Finally, the Compute Centroid
MATLAB Function block computes a centroid value from the detected area in the image by using hdl.iteratorfun
.
Open the hdlFrame_ObjectDetecting/DUT
subsystem to see the object detection algorithm.
load_system('hdlFrame_ObjectDetecting'); open_system('hdlFrame_ObjectDetecting/DUT');
Open the hdlFrame_ObjectDetecting/DUT/rgb2hsv
MATLAB Function block to see the RGB to HSV color space conversion algorithm.
open_system('hdlFrame_ObjectDetecting/DUT/rgb2hsv');
function [H, S, V] = rgb2hsv_frame(R, G, B) [H, S, V] = hdl.npufun(@rgb2hsvKernel, [1 1], R, G, B); end function [h, s, v] = rgb2hsvKernel(r, g, b) maxVal = max([r g b]); minVal = min([r g b]); delta = maxVal - minVal; h = single(0.0); if (r == maxVal) h = (g - b) / delta; end if (g == maxVal) h = (b - r) / delta + 2.0; end if (b == maxVal) h = (r - g) / delta + 4.0; end h = h/6.0; if h < 0.0 h = h + 1; end tmp = delta / maxVal; if (delta == 0.0) h = single(0.0); end if (maxVal ~= 0.0) s = tmp; else s = single(0.0); end v = maxVal; end
Open the hdlFrame_ObjectDetecting/DUT/Compute Centroid
block to see the centroid computation algorithm.
open_system('hdlFrame_ObjectDetecting/DUT/Compute Centroid');
function centroid = myCentroid_frame(BW) C = coder.const(int32(size(BW, 2))); sumRC = int32([0 0 0 0 0]); % centroidR, centroiC, RowCounter, ColCounter totalPoints centRC = hdl.iteratorfun(@kernel, BW, sumRC, C); recip = single(1)/single(centRC(5)); centR = int32(single(centRC(1))*recip); centC = int32(single(centRC(2))*recip); centroid = [centR, centC]; end function sumRC = kernel(bw, sumRC, idx, C) sumRC(3) = sumRC(3) + 1; % counter 1 rows % check for boundaries if sumRC(3) > C sumRC(3) = 1; sumRC(4) = sumRC(4) + 1; % counter 2 cols end if bw sumRC(1) = sumRC(1) + sumRC(3); sumRC(2) = sumRC(2) + sumRC(4); sumRC(5) = sumRC(5) + 1; end end
The model uses 2-D matrices as inputs to the DUT. These inputs signals are the separated R, G, and B components of the input image. Each input signal is a frame input matrix composed of 240x320 pixels. To see the frame size and simulation results, open the hdlFrame_ObjectDetecting/Output
block and simulate the model.
open_system('hdlFrame_ObjectDetecting/Output') sim("hdlFrame_ObjectDetecting");
Identify Streamed Signals
To generate synthesizable HDL code using the frame-to-sample conversion, identify the signals to be converted from frames to samples during HDL code generation. For this example, you convert the R
, G
, and B
input signals. The R, G, and B input signals are streamed signals in this example because they go through the frame-to-sample conversion optimization during HDL code generation. The frame-to-sample conversion detects if the output of the DUT is a streamed output signal, which is a converted frame-to-sample signal, or a non-streamed signal, which is any output that does not get transformed from frame to samples. In this example, the centroid value is a characteristic of the image, and is characterized as a non-streamed signal.
Close the hdlFrame_ObjectDetecting/Output
block and set the HDL block property ConvertToSamples
on the Inport blocks of the DUT that connect to the R, G, and B input signals to convert the input signals from frame-based to sample-based inputs during HDL code generation.
close_system('hdlFrame_ObjectDetecting/Output') hdlset_param('hdlFrame_ObjectDetecting/DUT/R', 'ConvertToSamples', 'on'); hdlset_param('hdlFrame_ObjectDetecting/DUT/G', 'ConvertToSamples', 'on'); hdlset_param('hdlFrame_ObjectDetecting/DUT/B', 'ConvertToSamples', 'on');
Generate HDL Code
Set the HDL block property Architecture
to MATLAB Datapath
on the MATLAB Function blocks inside DUT that convert image from RGB to HSV color space and compute the centroid.
hdlset_param('hdlFrame_ObjectDetecting/DUT/rgb2hsv', 'Architecture', 'MATLAB Datapath'); hdlset_param('hdlFrame_ObjectDetecting/DUT/Compute Centroid', 'Architecture', 'MATLAB Datapath');
Enable the frame-to-sample conversion optimization and generate HDL code using the makehdl
command.
hdlset_param('hdlFrame_ObjectDetecting', 'FrameToSampleConversion', 'on'); makehdl('hdlFrame_ObjectDetecting/DUT')
### Working on the model <a href="matlab:open_system('hdlFrame_ObjectDetecting')">hdlFrame_ObjectDetecting</a> ### Generating HDL for <a href="matlab:open_system('hdlFrame_ObjectDetecting/DUT')">hdlFrame_ObjectDetecting/DUT</a> ### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlFrame_ObjectDetecting', { 'HDL Code Generation' } )">hdlFrame_ObjectDetecting</a> for HDL code generation parameters. ### Running HDL checks on the model 'hdlFrame_ObjectDetecting'. ### Begin compilation of the model 'hdlFrame_ObjectDetecting'... ### Working on the model 'hdlFrame_ObjectDetecting'... ### The code generation and optimization options you have chosen have introduced additional pipeline delays. ### The delay balancing feature has automatically inserted matching delays for compensation. ### The DUT requires an initial pipeline setup latency. Each output port experiences these additional delays. ### Output port 1: 177 cycles. ### Output port 1: The first valid output of this port will be after an initial latency of 76799 valid inputs. ### Output port 2: 177 cycles. ### Output port 2: The first valid output of this port will be after an initial latency of 76799 valid inputs. ### Working on... <a href="matlab:configset.internal.open('hdlFrame_ObjectDetecting', 'GenerateModel')">GenerateModel</a> ### Begin model generation 'gm_hdlFrame_ObjectDetecting'... ### Rendering DUT with optimization related changes (IO, Area, Pipelining)... ### Model generation complete. ### Generated model saved at <a href="matlab:open_system('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/gm_hdlFrame_ObjectDetecting.slx')">hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/gm_hdlFrame_ObjectDetecting.slx</a> ### Estimated critical path for design: <a href="matlab:run('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/criticalPathEstimated')">hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/criticalPathEstimated.m</a> ### Delay absorption obstacles can be diagnosed by running this script: <a href="matlab:run('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/highlightDelayAbsorption')">hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/highlightDelayAbsorption.m</a> ### Blocks that are not characterized for Critical Path Estimation: <a href="matlab:run('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/highlightCriticalPathEstimationOffendingBlocks')">hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/highlightCriticalPathEstimationOffendingBlocks.m</a> ### To clear highlighting, click the following MATLAB script: <a href="matlab:run('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/clearhighlighting.m')">hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/clearhighlighting.m</a> ### Generating new validation model: '<a href="matlab:open_system('hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/gm_hdlFrame_ObjectDetecting_vnl')">gm_hdlFrame_ObjectDetecting_vnl</a>'. ### Validation model generation complete. ### Begin VHDL Code Generation for 'hdlFrame_ObjectDetecting'. ### MESSAGE: The design requires 76800 times faster clock with respect to the base rate = 0.0166667. ### Working on... <a href="matlab:configset.internal.open('hdlFrame_ObjectDetecting', 'Traceability')">Traceability</a> ### Working on hdlFrame_ObjectDetecting/DUT/FindTarget/HSVtoBW/nfp_sub_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_sub_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel/nfp_relop_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_relop_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel/nfp_add_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_add_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel/nfp_div_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_div_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/FindTarget/HSVtoBW/nfp_relop_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_relop_single_block.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel/nfp_relop_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_relop_single_block1.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel/nfp_relop_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_relop_single_block2.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv/rgb2hsvKernel as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/rgb2hsvKernel.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/rgb2hsv as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/rgb2hsv.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/FindTarget/HSVtoBW/nfp_abs_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_abs_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/FindTarget/HSVtoBW as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/HSVtoBW.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/FindTarget as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/FindTarget.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid/kernel as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/kernel.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid/nfp_convert_single_to_sfix_32_En0 as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_convert_single_to_sfix_32_En0.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid/nfp_mul_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_mul_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid/nfp_recip_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_recip_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid/nfp_convert_sfix_32_En0_to_single as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/nfp_convert_sfix_32_En0_to_single.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Compute Centroid as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/Compute_Centroid.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Input_FIFOs/R_FIFO/FIFO/FIFO_classic/SimpleDualPortRAM_generic as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/SimpleDualPortRAM_generic.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Input_FIFOs/R_FIFO as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/R_FIFO.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Input_FIFOs/G_FIFO as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/G_FIFO.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Input_FIFOs/B_FIFO as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/B_FIFO.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Input_FIFOs as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/Input_FIFOs.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Output_FIFOs/centroid_memory as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/centroid_memory.vhd. ### Working on hdlFrame_ObjectDetecting/DUT/Output_FIFOs as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/Output_FIFOs.vhd. ### Working on hdlFrame_ObjectDetecting/DUT as hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/DUT.vhd. ### Generating package file hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/DUT_pkg.vhd. ### Code Generation for 'hdlFrame_ObjectDetecting' completed. ### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24b_2679053_1563133/tp30ea4710/hdlcoder-ex10871504/hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/html/hdlFrame_ObjectDetecting_codegen_rpt.html')">hdlFrame_ObjectDetecting_codegen_rpt.html</a> ### Creating HDL Code Generation Check Report file:///tmp/Bdoc24b_2679053_1563133/tp30ea4710/hdlcoder-ex10871504/hdl_prj/hdlsrc/hdlFrame_ObjectDetecting/DUT_report.html ### HDL check for 'hdlFrame_ObjectDetecting' complete with 0 errors, 0 warnings, and 4 messages. ### HDL code generation complete.
The frame-to-sample conversion separates the frame-based inputs into sample, valid, and ready signals for a sample-based hardware-targeted interface.