Main Content

Top-Hat Filtering to Remove Uneven Background Illumination on NVIDIA Jetson TX2 Developer Kit

This example shows how to deploy Image Processing Toolbox™ algorithms to NVIDIA® Jetson TX2 board using the GPU Coder™ Support Package for NVIDIA GPUs. The imtophat (Image Processing Toolbox) function that performs morphological top-hat filtering on a grayscale image is used as an example to demonstrate this concept. Top-hat filtering computes the morphological opening of the image (using imopen (Image Processing Toolbox)) and then subtracts the result from the original image. The generated CUDA® code uses shared memory to speed up the operations on the GPU.

Prerequisites

Target Board Requirements *

  • NVIDIA Jetson TX2 embedded platform.

  • Ethernet crossover cable to connect the target board and host PC (if the target board cannot be connected to a local network).

  • NVIDIA CUDA toolkit installed on the board.

  • OpenCV library on the target for reading and displaying images and video.

  • Environment variables on the target for the compilers and libraries. For information on the supported versions of the compilers and libraries and their setup, see Install and Setup Prerequisites for NVIDIA Boards for NVIDIA boards.

Development Host Requirements

  • CUDA enabled NVIDIA GPU.

  • NVIDIA CUDA toolkit and driver.

  • Environment variables for the compilers and libraries. For information on the supported versions of the compilers and libraries, see Third-Party Hardware. For setting up the environment variables, see Setting Up the Prerequisite Products.

Verify NVIDIA Support Package Installation on Host

Use the checkHardwareSupportPackageInstall function to verify that the host system is compatible to run this example.

checkHardwareSupportPackageInstall();

Connect to the NVIDIA Hardware

The GPU Coder Support Package for NVIDIA GPUs uses an SSH connection over TCP/IP to execute commands while building and running the generated CUDA code on the Jetson platform. You must therefore connect the target platform to the same network as the host computer or use an Ethernet crossover cable to connect the board directly to the host computer. Refer to the NVIDIA documentation on how to set up and configure your board.

To communicate with the NVIDIA hardware, you must create a live hardware connection object by using the jetson function. You must know the host name or IP address, username, and password of the target board to create a live hardware connection object.

hwobj= jetson('host-name','username','password');

When there are multiple live connection objects for different targets, the code generator performs remote build on the target for which a recent live object was created. To choose a hardware board for performing remote build, use the setupCodegenContext() method of the respective live hardware object. If only one live connection object was created, it is not necessary to call this method.

hwobj.setupCodegenContext;

Verify GPU Environment

To verify that the compilers and libraries necessary for running this example are set up correctly, use the coder.checkGpuInstall function.

envCfg = coder.gpuEnvConfig('jetson');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
envCfg.HardwareObject = hwobj;
coder.checkGpuInstall(envCfg);

The imtophat Entry-Point Function

The imtophatDemo_gpu.m calls imtophat internally. The imtophat function performs morphological opening on the image using the imopen (Image Processing Toolbox) function. The result of the image is subtracted from the original image. The imopen operation is basically imerode (Image Processing Toolbox) operation followed by imdilate (Image Processing Toolbox).

This example is shown on an input grayscale image.

original = imread('rice.png');
imshow(original),title('Input to Top-Hat Filtering');

Create a disc-shaped structuring element with a radius of 12. Neighborhood, Nhood of this structuring element is passed as an input argument for the imtophat function.

se = strel('disk',12);
Nhood = se.Neighborhood;
type imtophatDemo_gpu
function [out]  = imtophatDemo_gpu(img,Nhood,ocvFlag) %#codegen

%   Copyright 2019-2021 The MathWorks, Inc.   

coder.gpu.kernelfun;

% This example uses OpenCV for reading an image 
% and displaying output image. Update buildinfo to link with 
% OpenCV library available on target.
if ocvFlag 
    % OpenCV 4 flags
    opencv_compile_flags = '`pkg-config --cflags --libs opencv4`';
    opencv_link_flags = '`pkg-config --libs opencv4`';
else 
    % OpenCV 3 flags
    opencv_compile_flags = '`pkg-config --cflags --libs opencv`';
    opencv_link_flags = '`pkg-config --libs opencv`';
end

coder.updateBuildInfo('addLinkFlags',opencv_link_flags);
coder.updateBuildInfo('addCompileFlags',opencv_compile_flags);

out = imtophat(img,Nhood);

end

Get OpenCV Version on the Target

Use the pkg-config helper tool to query if OpenCV 4.x is installed on the target board. This example uses the information to update build information to link with the appropriate OpenCV library available on target.

isOpenCV4 = 1;
ocvVersion = hwobj.OpenCVVersion();
if (str2double(ocvVersion(1)) <= 3)
   isOpenCV4 = 0;
end

Generate and Deploy CUDA Code on the Target

This example uses imtophatDemo_gpu.m as the entry-point function for code generation. To generate a CUDA executable, create a GPU code configuration object.

cfg = coder.gpuConfig('exe');

Use the coder.hardware function to create a configuration object for the Jetson platform and assign it to the Hardware property of the GPU code configuration object cfg.

cfg.Hardware = coder.hardware('NVIDIA Jetson');

The custom main_tophat.cu file is a wrapper that calls the imtophatDemo_gpu entry-point function in the generated code. Post processing steps are added in the main file using OpenCV interfaces. Build Flags for OpenCV libraries are included in imtophatDemo_gpu.m entry-point function.

cfg.CustomSource = fullfile('main_tophat.cu');

To generate CUDA code, use the codegen function and pass the GPU code configuration object along with input arguments. In this step, CUDA code is generated on the host, generated files are copied over and built on the target in the workspace directory. The workspace directory is available as a property, workspaceDir in the hardware object, hwobj.

codegen -args {original,coder.Constant(Nhood),coder.Constant(isOpenCV4)} -config cfg imtophatDemo_gpu -report

Run the Application on the Target

This application takes a grayscale image as input. Copy the rice.png file from host to the target device by using the putFile command.

imgLoc = which('rice.png');
hwobj.putFile(imgLoc,hwobj.workspaceDir);

Use the runApplication method of the hardware object to launch the application on the target hardware.

hwobj.runApplication('imtophatDemo_gpu','rice.png');

Top-Hat Filtered Image on Jetson TX2

Kill the Application

Use the killApplication method of the hardware object to kill the running application on the target.

hwobj.killApplication('imtophatDemo_gpu');

See Also

Objects

Related Topics