Store video lines and return neighborhood pixels
System object™ selects neighborhood pixels from streaming image data. It handles video control
signals and edge padding, and is pipelined for high-speed video designs. The object outputs
one column of the neighborhood at a time. To compose a neighborhood for further processing,
shiftEnable signal to store the output columns, including padding,
in a shift register. This object allows you to share the line buffer resources when your
design performs multiple operations on the same neighborhood.
The following waveform shows the
visionhdl.LineBuffer object returning 5-by-1 pixel columns that make up a
5-by-5 neighborhood. The time frame shown is at the beginning (top-left corner) of an input
frame. The output starts after the object has stored two (
and is receiving the start of the third line. The
shiftEnable signal is
asserted two cycles earlier than the output
ctrl.valid signal, which
indicates that the first two (
floor(M/2)) columns are exclusively padding
shiftEnable stays high for two extra cycles at the end
of the line.
To extract sliding pixel neighborhoods from a video stream:
visionhdl.LineBuffer object and set its properties.
Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?.
linemem = visionhdl.LineBuffer(
returns a line buffer System object. Set properties using name-value pairs. Enclose each property name in single
linemem = visionhdl.LineBuffer('NeighborhoodSize',[5 5])
Unless otherwise indicated, properties are nontunable, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
release function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects.
NeighborhoodSize— Size of output neighborhood
[3 3](default) | 2-element row vector of integer dimensions
Size of output neighborhood to be formed, specified as a 2-element row vector of integer dimensions [vertical horizontal]. The object returns a column vector of vertical elements. The horizontal dimension is used to determine padding.
PaddingMethod— Method for padding the boundary of input image
Select one of these methods for padding the boundary of the input image.
'Constant' — Interpret pixels outside the image frame as having a constant value.
'Replicate' — Repeat the value of pixels at the edge of the image.
'Symmetric' — Set the value of the padding pixels to mirror the edge of the image.
'None' — Exclude padding logic. The object does not set the pixels
outside the image frame to any particular value. This option reduces the hardware resources
used by the object and the blanking required between frames but affects the accuracy of the
output pixels at the edges of the frame. To maintain pixel stream timing, the output frame
is the same size as the input frame. However, to avoid using pixels calculated from
undefined padding values, mask off the KernelSize/2 pixels around the
edge of the frame for downstream operations. For details, see Increase Throughput with Padding None.
For more information about these methods, see Edge Padding.
PaddingValue— Value used to pad boundary of input image
0(default) | integer
Value used to pad the boundary of the input image, specified as an integer. The object casts this value to the same data type as the input pixel.
This property is valid when you set
LineBufferSize— Size of line memory buffer
2048(default) | positive integer
Specify a power of two that accommodates the number of active pixels in a single horizontal line.
If you specify a value that is not a power of two, the object uses the next largest power of two.
This object uses a streaming pixel interface with a structure
for frame control signals. This interface enables the object to operate independently of image
size and format, and to connect with other Vision HDL Toolbox™ objects. The object accepts and returns a scalar pixel value and control signals
as a structure containing five signals. The control signals indicate the validity of each pixel
and its location in the frame. To convert a pixel matrix into a pixel stream and control
signals, use the
visionhdl.FrameToPixels object. For a full
description of the interface, see Streaming Pixel Interface.
You can simulate System objects with a multipixel streaming interface, but System objects are not supported for HDL code generation. Use the equivalent blocks to generate HDL code for multipixel algorithms.
pixelIn— Single image pixel
Single image pixel in a pixel stream, specified as a scalar value representing intensity.
types are supported for simulation, but not for HDL code generation.
pixelOut— Single column of neighborhood
Single column neighborhood pixel values, returned as a of 1-by-M vector, where M is the vertical neighborhood dimension. The output pixel data type is the same as the data type of the input pixels.
To compose a neighborhood for further processing, use the
shiftEnable signal to store the output columns, including
padding, in a shift register.
HDL code generation is supported for small matrices, but matrix operations can impact hardware performance and resource usage. Therefore, minimize how much your design operates on an N-by-M neighborhood directly. You can :
Separate a filter into vertical and horizontal components.
Concatenate the neighborhood pixels into a N*M-by-1 vector.
These design suggestions also provide opportunities to add pipelining around each adder or multiplier to increase synthesized clock speed and fit the design to DSP blocks on an FPGA.
ctrlOut— Control signals accompanying output column
Control signals accompanying pixel stream, returned as a structure containing five
logical signals. The signals describe the validity of the center
pixel of the column, and the location of that pixel within the frame. See Pixel Control Structure.
Columns that contain only padding pixels do not assert
shiftEnable signal is asserted
for both padding and active columns.
For most of the frame, the object returns the input control signals that arrived
with the bottom pixel of the column. However, for the final
floor(M/2) lines of each frame, the bottom
pixel of the column is a padding pixel, so the object generates output control
signals. The object generates a contiguously asserted
signal for the valid pixels in each line.
To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named
visionhdl.LineBuffer System object™ stores video lines and returns sliding neighborhoods for kernel-based image operations. This example calculates the average of each neighborhood.
Import image source and set up serializer and deserializer objects.
frmOrig = imread('rice.png'); frmActivePixels = 48; frmActiveLines = 32; frmIn = frmOrig(1:frmActiveLines,1:frmActivePixels); figure imshow(frmIn,'InitialMagnification',300) title 'Input Image' frm2pix = visionhdl.FrameToPixels(... 'NumComponents',1,... 'VideoFormat','custom',... 'ActivePixelsPerLine',frmActivePixels,... 'ActiveVideoLines',frmActiveLines,... 'TotalPixelsPerLine',frmActivePixels+10,... 'TotalVideoLines',frmActiveLines+10,... 'StartingActiveLine',6,... 'FrontPorch',5); [~,~,numPixPerFrm] = getparamfromfrm2pix(frm2pix); pix2frm = visionhdl.PixelsToFrame(... 'NumComponents',1,... 'VideoFormat','custom',... 'ActivePixelsPerLine',frmActivePixels,... 'ActiveVideoLines',frmActiveLines);
Write a function that creates and calls the System object™. The object returns one column of the neighborhood at a time. Use a shift register to save the columns. Then, calculate the average of the pixel neighborhood. You can generate HDL from this function.
Note: This object syntax runs only in R2016b or later. If you are using an earlier release, replace each call of an object with the equivalent
step syntax. For example, replace
function [pixOut,ctrlOut] = AvgFilter(pixIn,ctrlIn) %AvgFilter % Calculates the average pixel value for each 3x3 kernel % pixIn and pixOut are scalar uint8 pixel values. % ctrlIn and ctrlOut are structures that contain control signals associated % with the pixel. % You can generate HDL code from this function. persistent linemem; if isempty(linemem) linemem = visionhdl.LineBuffer; end persistent dataShiftReg; if isempty(dataShiftReg) % use typeof(pixIn)? dataShiftReg = fi(zeros(3,3),0,8,0); end % HDL code gen does not support arrays of structs persistent controlShiftReg1; persistent controlShiftReg2; persistent controlShiftReg3; if isempty(controlShiftReg1) controlShiftReg1 = pixelcontrolstruct(); controlShiftReg2 = pixelcontrolstruct(); controlShiftReg3 = pixelcontrolstruct(); end persistent div9; if isempty(div9) div9 = fi(1/9,0,12,15); end % Advance shift registers dataShiftReg(:,2:end) = dataShiftReg(:,1:end-1); controlShiftReg3 = controlShiftReg2; controlShiftReg2 = controlShiftReg1; % Fetch next column [dataShiftReg(:,1),controlShiftReg1] = linemem(fi(pixIn,0,8,0),ctrlIn); % Calculate the average over the neighborhood pixOut = uint8((sum(dataShiftReg(:),'native')).*div9); ctrlOut = controlShiftReg3; end
Process the image by calling the function for each pixel.
pixOutVec = ones(numPixPerFrm,1,'uint8'); ctrlOutVec = repmat(pixelcontrolstruct(false,false,false,false,false),numPixPerFrm,1); [pixInVec,ctrlInVec] = frm2pix(frmIn); for p = 1:numPixPerFrm [pixOutVec(p),ctrlOutVec(p)] = AvgFilter(pixInVec(p),ctrlInVec(p)); end
Recreate the filtered frame.
[frmOut,frmValid] = step(pix2frm,pixOutVec,ctrlOutVec); if frmValid figure; imshow(frmOut,'InitialMagnification',300) title 'Output Image' end
The object stores M – 1 lines of valid pixels, as specified by the
neighborhood size. It adds padding bits at the edge of the frame. The object returns the first
output column once it can form a complete neighborhood column, which occurs at the start of