This example demonstrates edge detection in an image with a CUDA® MEX function generated from a MATLAB® function. The edge detection algorithm is implemented with half-precision data type.
Required
This example generates CUDA MEX and has the following third-party requirements.
CUDA enabled NVIDIA® GPU with a minimum compute capability of 5.3 and compatible driver.
Optional
For non-MEX builds such as static, dynamic libraries or executables, this example has the following additional requirements.
NVIDIA toolkit.
Environment variables for the compilers and libraries. For more information, see Third-Party Hardware and Setting Up the Prerequisite Products.
To verify that the compilers and libraries necessary for running this example are set up correctly, use the coder.checkGpuInstall
function.
envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);
In the Sobel edge detection algorithm (sobelEdgeDetectionAlg.m) , a 2-D spatial gradient operation is performed on a gray scale image. This operation emphasizes the high spatial frequency regions that correspond to the edges in the image.
type sobelEdgeDetectionAlg
function edgeImg = sobelEdgeDetectionAlg(img,thresh) %#codegen %sobelEdgeDetection Example MATLAB function for edge detection. % Copyright 2018 The MathWorks, Inc. kern = half([1 2 1; 0 0 0; -1 -2 -1]); % Finding horizontal and vertical gradients. h = conv2(img(:,:,2),kern,'same'); v = conv2(img(:,:,2),kern','same'); % Finding magnitude of the gradients. e = sqrt(h.*h + v.*v); % Threshold the edges edgeImg = uint8((e > thresh) * 240); end
The Sobel edge algorithm computes the horizontal gradient resX
and the vertical gradient resY
of the input image by using two orthogonal filter kernels maskX
and maskY
. After the filtering operation, the algorithm computes the gradient magnitude and applies a threshold to find the regions of the images that are considered to be edges.
Use the standard imread
command to read the images. imread
represents the RGB channels of an images with integers, one for each pixel. The integers range from 0 to 255. Simply casting inputs to half type might result in overflow during convolutions. In this case, we can scale the images to values between 0 and 1.
im = imread('peppers.png');
figure();
image(im);
imPacked = half(im)/255;
thresh = half(100)/255;
To generate CUDA MEX for the sobelEdgeDetectionAlg
function, create a GPU code configuration object and run the codegen
command. To generate and execute code with half-precision data types, CUDA compute capability of 5.3 or higher is required. Set the ComputeCapability
property of the code configuration object to '5.3'
. For half-precision, the memory allocation (malloc) mode for generating CUDA code must be set to 'Discrete'.
cfg = coder.gpuConfig('mex'); cfg.GpuConfig.ComputeCapability = '5.3'; cfg.GpuConfig.MallocMode = 'Discrete'; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg;
After you generate a MEX function, you can verify that it has the same functionality as the original MATLAB entry-point function. Run the generated sobelEdgeDetectionAlg_mex
and plot the results.
out_disp = sobelEdgeDetectionAlg_mex(imPacked,thresh); imagesc(out_disp);
Clear the static network object that was loaded in memory.
clear mex;