Morphologically open binary pixel stream
System object™ morphologically opens a binary pixel stream. This operation
morphologically erodes and then morphologically dilates each pixel by using the same
neighborhood for both calculations. The object operates on a stream of binary intensity
To morphologically open a binary pixel stream:
visionhdl.Openingobject 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?
System object that morphologically opens a binary pixel stream.
opener = visionhdl.Opening
sets properties using one or more name-value arguments. For example,
opener = visionhdl.Opening(
'Neighborhood',getnhood(strel('disk',4)) specifies a
4-by-4 disk-pattern neighborhood.
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.
Neighborhood — Pixel neighborhood
ones(3,3) (default) | vector or matrix of binary values
Pixel neighborhood, specified as a vector or matrix of binary values.
The object supports neighborhoods of up to 32-by-32 pixels. To
use a structuring element, set the
Neighborhood property to
shape is specified by the input arguments to the
strel (Image Processing Toolbox) function.
LineBufferSize — Size of line memory buffer
2048 (default) | positive integer
Size of the line memory buffer, specified as a positive integer. Choose a power of two that accommodates the number of active pixels in a horizontal line. If you specify a value that is not a power of two, the buffer uses the next largest power of two.
The object allocates (n –
LineBufferSize memory locations to store the pixels,
where n is the number of lines in the
Neighborhood property value.
PaddingMethod — Method for padding boundary of input image
'Constant' (default) |
Method for padding the boundary of the input image, specified as one of these values.
'Constant'— The object pads the image with ones for the erosion operation and with zeros for the dilation operation. These values prevent opening at the boundaries of the active frame.
'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 that are used by the object and reduces the blanking that is required between frames. However, this option 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 n/2 pixels around the edge of the frame for downstream operations. n is the size of the operation kernel. For more details, see Increase Throughput with Padding None.
For more information about these methods, see Edge Padding.
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
description of the interface, see Streaming Pixel Interface.
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
Morphologically Open an Image
Load a source image from a file. Select a portion of the image that matches the desired test size. This source image contains pixel intensity values of
uint8 data type. Apply a threshold to convert the pixel data to binary values.
frmOrig = imread('rice.png'); frmActivePixels = 64; frmActiveLines = 48; frmInput = frmOrig(1:frmActiveLines,1:frmActivePixels); frmInput = frmInput>128; figure imshow(frmInput,'InitialMagnification',300) title 'Input Image'
Create a serializer System object™ and define inactive pixel regions. Set the number of inactive pixels following each active line to at least double the horizontal size of the neighborhood. Set the number of lines following each frame to at least double the vertical size of the neighborhood.
frm2pix = visionhdl.FrameToPixels(... 'NumComponents',1, ... 'VideoFormat','custom', ... 'ActivePixelsPerLine',frmActivePixels, ... 'ActiveVideoLines',frmActiveLines, ... 'TotalPixelsPerLine',frmActivePixels+20, ... 'TotalVideoLines',frmActiveLines+10, ... 'StartingActiveLine',3, ... 'FrontPorch',10);
Create a morphological open System object.
opener = visionhdl.Opening(... 'Neighborhood',ones(5,5));
Serialize the test image by calling the serializer object.
pixin is a vector of intensity values.
ctrlin is a vector of control signal structures.
[pixin,ctrlin] = frm2pix(frmInput);
Prepare to process the pixel stream by preallocating output vectors.
[~,~,numPixelsPerFrame] = getparamfromfrm2pix(frm2pix); pixout = false(numPixelsPerFrame,1); ctrlout = repmat(pixelcontrolstruct,numPixelsPerFrame,1);
For each pixel in the padded frame, compute the morphed value. Monitor the control signals to determine latency of the object. The latency of a configuration depends on the number of active pixels in a line and the size of the neighborhood.
foundValIn = false; foundValOut = false; for p = 1:numPixelsPerFrame if (ctrlin(p).valid && foundValIn==0) foundValIn = p; end [pixout(p),ctrlout(p)] = opener(pixin(p),ctrlin(p)); if (ctrlout(p).valid && foundValOut==0) foundValOut = p; end end objLatency_cycles= foundValOut - foundValIn
objLatency_cycles = 368
Create a deserializer System object with a format that matches the serializer format. Convert the pixel stream to an image frame by calling the deserializer object. Display the resulting image.
pix2frm = visionhdl.PixelsToFrame(... 'NumComponents',1, ... 'VideoFormat','custom', ... 'ActivePixelsPerLine',frmActivePixels, ... 'ActiveVideoLines',frmActiveLines, ... 'TotalPixelsPerLine',frmActivePixels+20); [frmOutput,frmValid] = pix2frm(pixout,ctrlout); if frmValid figure imshow(frmOutput,'InitialMagnification',300) title 'Output Image' end
This object implements the algorithms described on the Opening block reference page.
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
This System object supports C/C++ code generation for accelerating MATLAB® simulations, and for DPI component generation. For more information about acceleration, see Accelerate Pixel-Streaming Designs Using MATLAB Coder. For more information about DPI component generation, see Considerations for DPI Component Generation with MATLAB (HDL Verifier).
HDL Code Generation
Generate Verilog and VHDL code for FPGA and ASIC designs using HDL Coder™.
To generate HDL code from Vision HDL Toolbox System objects, see Design Hardware-Targeted Image Filters in MATLAB.
Version HistoryIntroduced in R2015a
R2020a: Option to omit padding
You can now configure the object to not add padding around the boundaries of the
active frame. This option reduces the hardware resources used by the object and
reduces the blanking interval required between frames but affects the accuracy of
the output pixels at the edges of the frame. To use this option, set the
PaddingMethod property to
R2020a: Multipixel streaming
The object now supports multipixel streams. For multipixel streaming, the object
supports input and output column vectors of 4 or 8 pixels. The
ctrl argument remains scalar, and the control signals in
pixelcontrol structure apply to all pixels in the
You can simulate System objects with a multipixel streaming interface, but you cannot generate HDL code for System objects that use multipixel streams. To generate HDL code for multipixel algorithms, use the equivalent Simulink blocks.
R2018b: Improved line buffer
The internal line buffer in this object now handles bursty data, that is,
noncontiguous valid signals within a pixel line. This implementation uses fewer
hardware resources due to improved padding logic and native support for kernel sizes
with an even number of lines. This change affects the
visionhdl.LineBuffer object and objects that use an internal
The latency of the line buffer is now reduced by a few cycles for some configurations. You might need to rebalance parallel path delays in your designs. A best practice is to synchronize parallel paths in your designs by using the pixel stream control signals rather than by inserting a specific number of delays.