Morphology
Overview
The Morphology sample demonstrates GPU-accelerated morphological image processing using CV-CUDA. It applies a dilation followed by an erosion (equivalent to a morphological close operation) to fill small dark gaps while preserving the main structures of the image. The sample illustrates how to choose a structuring element size and how to supply a workspace tensor when required.
Usage
Basic Usage
Apply morphological close (dilate then erode) with a 5×5 kernel to the default cat image:
python3 morphology.py -i input.jpg
Custom Input
Process a different image and save the result explicitly:
python3 morphology.py -i image.jpg -o cat_morphology.jpg
Command-Line Arguments
Argument |
Short Form |
Default |
Description |
|---|---|---|---|
|
|
tabby_tiger_cat.jpg |
Input image file path |
|
|
cvcuda/.cache/cat_morphology.jpg |
Output image file path |
Implementation
Morphological Close (Dilate then Erode)
# Wrap the HWC single image in a batch dimension (NHWC) so the morphology
# operator can process it. The operator accepts both HWC and NHWC layouts.
nhwc_image: cvcuda.Tensor = input_image.reshape((1, *input_image.shape), "NHWC")
# A 5x5 rectangular structuring element is large enough to show a visible
# effect on a natural image without destroying structure.
mask_size = [5, 5]
# anchor=[-1, -1] centres the structuring element automatically.
anchor = [-1, -1]
# DILATE expands bright regions — edges become thicker and fine dark lines
# are reduced. A workspace tensor is not required for a single iteration.
dilated: cvcuda.Tensor = cvcuda.morphology(
nhwc_image,
cvcuda.MorphologyType.DILATE,
mask_size,
anchor,
iteration=1,
border=cvcuda.Border.REPLICATE,
)
# ERODE is the dual of dilation — it shrinks bright regions and removes
# small bright specks. Running erode after dilate is a CLOSE operation,
# which suppresses small dark artifacts/holes while preserving larger
# structures.
workspace: cvcuda.Tensor = cvcuda.Tensor(
nhwc_image.shape, nhwc_image.dtype, nhwc_image.layout
)
closed: cvcuda.Tensor = cvcuda.morphology(
dilated,
cvcuda.MorphologyType.ERODE,
mask_size,
anchor,
iteration=1,
border=cvcuda.Border.REPLICATE,
workspace=workspace,
)
# Remove the batch dimension before writing; write_image expects HWC.
result: cvcuda.Tensor = closed.reshape(closed.shape[1:], "HWC")
write_image(result, args.output)
Key points:
Batch reshape: The HWC tensor returned by
read_imageis reshaped to NHWC before calling the operator, which accepts both layouts.Structuring element:
mask_size=[5, 5]selects a 5×5 rectangular kernel;anchor=[-1, -1]auto-centres it.DILATE then ERODE: Applying dilation followed by erosion is a morphological close, which fills small dark holes and gaps while keeping large bright structures intact.
Workspace tensor: A workspace tensor of the same shape and dtype as the input is required when passing the result of one morphological call into a second one; it is used internally by the operator as scratch memory.
Output reshape: The NHWC result is reshaped back to HWC before
write_imageto produce a standard single-image output.
Expected Output
The output shows the image after morphological closing — small dark gaps are filled and bright regions are slightly expanded:
Original Input Image |
Output: Morphological Close (5×5 kernel) |
CV-CUDA Operators Used
Operator |
Purpose |
|---|---|
Apply dilation and erosion with a rectangular structuring element |
Common Utilities Used
read_image() - Load image as CV-CUDA tensor
write_image() - Save the morphologically processed image
parse_image_args() - Parse
--input/--outputCLI arguments
See Also
Resize Operator - Basic spatial transform operator
Common Utilities - Helper functions used across samples