Edge Detection with Sobel Method in Half-Precision
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.
Third-Party Prerequisites
Required
This example generates CUDA MEX and has the following third-party requirements.
CUDA enabled NVIDIA® GPU with a minimum compute capability of 6.0 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.
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('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);
Sobel Edge Detection Algorithm
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.
Read Images and Pack Data Into RGBA Packed Column Major Order
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;
Generate CUDA MEX for the Function
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 6.0 or higher is required. Set the ComputeCapability
property of the code configuration object to '6.0'
. For half-precision, the memory allocation (malloc) mode for generating CUDA code must be set to 'Discrete'.
cfg = coder.gpuConfig('mex'); cfg.GpuConfig.ComputeCapability = '6.0'; cfg.GpuConfig.MallocMode = 'Discrete'; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg;
Code generation successful.
Run the MEX Function
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 MEX Memory.
Clear the static network object that was loaded in memory.
clear mex;
See Also
Functions
codegen
|coder.gpu.kernel
|coder.gpu.kernelfun
|gpucoder.matrixMatrixKernel
|coder.gpu.constantMemory
|gpucoder.stencilKernel
|coder.checkGpuInstall