Generate Code for Sobel Edge Detection That Uses Half-Precision Data Type
This example shows how to generate a standalone C++ library from a MATLAB® function that performs Sobel edge detection of images by using half-precision floating point numbers. The Sobel edge algorithm accepts an image that is represented as a matrix and returns an image emphasizing the high spatial frequency regions that correspond to its edges. This example also shows how to test the generated code by using a MEX function.
Sobel Edge Detection Algorithm
In the Sobel edge detection algorithm, a 2-D spatial gradient operation is performed on a grayscale 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 % Entry-point function for half-precision Sobel edge detection example. % Copyright 2018-2022 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 h
and the vertical gradient v
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 image that correspond to the edges.
Read Images and Pack Data Into RGBA Packed Column Major Order
Use the imread
function 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. To avoid this issue, 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 MEX
Generate a C++ MEX function for the sobelEdgeDetectionAlg
function by using the codegen
command.
cfg = coder.config('mex'); cfg.TargetLang = 'C++'; cfg.GenerateReport = true; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg
Code generation successful: To view the report, open('codegen/mex/sobelEdgeDetectionAlg/html/report.mldatx')
Run Generated MEX and Display Detected Edge
Before generating C++ code, you must first test the MEX function inside MATLAB environment to make sure that it is functionally equivalent to the original MATLAB code and that no run-time errors occur. By default, codegen
generates a MEX function named sobelEdgeDetectionAlg_mex
in the current folder. This allows you to test the MATLAB code and MEX function and compare the results.
out_disp = sobelEdgeDetectionAlg_mex(imPacked,thresh); figure(); imagesc(out_disp);
Generate Static C++ Library
Use the codegen
command to produces a C++ static library. By default, the generated library is located in the folder codegen/lib/sobelEdgeDetectionAlg/
.
cfg = coder.config('lib'); cfg.TargetLang = 'C++'; cfg.GenerateReport = true; codegen -config cfg -args {imPacked,thresh} sobelEdgeDetectionAlg;
Code generation successful: To view the report, open('codegen/lib/sobelEdgeDetectionAlg/html/report.mldatx')
Inspect the Generated Function
type codegen/lib/sobelEdgeDetectionAlg/sobelEdgeDetectionAlg.cpp
// // Prerelease License - for engineering feedback and testing purposes // only. Not for sale. // File: sobelEdgeDetectionAlg.cpp // // MATLAB Coder version : 24.2 // C/C++ source code generated on : 20-Jul-2024 12:19:40 // // Include Files #include "sobelEdgeDetectionAlg.h" #include "conv2MovingWindowSameCM.h" #include "rtwhalf.h" #include "sobelEdgeDetectionAlg_data.h" #include "sobelEdgeDetectionAlg_initialize.h" #include <cmath> // Function Definitions // // Entry-point function for half-precision Sobel edge detection example. // Copyright 2018-2022 The MathWorks, Inc. // // Arguments : const real16_T img[589824] // real16_T thresh // unsigned char edgeImg[196608] // Return Type : void // void sobelEdgeDetectionAlg(const real16_T img[589824], real16_T thresh, unsigned char edgeImg[196608]) { static const real16_T hv[9]{real16_T(1.0F), real16_T(0.0F), real16_T(-1.0F), real16_T(2.0F), real16_T(0.0F), real16_T(-2.0F), real16_T(1.0F), real16_T(0.0F), real16_T(-1.0F)}; static const real16_T hv1[9]{ real16_T(1.0F), real16_T(2.0F), real16_T(1.0F), real16_T(0.0F), real16_T(0.0F), real16_T(0.0F), real16_T(-1.0F), real16_T(-2.0F), real16_T(-1.0F)}; static real16_T h[196608]; static real16_T v[196608]; if (!isInitialized_sobelEdgeDetectionAlg) { sobelEdgeDetectionAlg_initialize(); } // Finding horizontal and vertical gradients. coder::conv2MovingWindowSameCM(&img[196608], hv, h); coder::conv2MovingWindowSameCM(&img[196608], hv1, v); // Finding magnitude of the gradients. // Threshold the edges for (int k{0}; k < 196608; k++) { real16_T b_h; real16_T h1; b_h = h[k]; h1 = v[k]; b_h = static_cast<real16_T>( std::sqrt(static_cast<float>(b_h * b_h + h1 * h1))); h[k] = b_h; edgeImg[k] = static_cast<unsigned char>((b_h > thresh) * 240U); } } // // File trailer for sobelEdgeDetectionAlg.cpp // // [EOF] //
See Also
half
| codegen
| coder.config
Related Topics
- Floating-Point Numbers (Fixed-Point Designer)