Generate Code for Sobel Edge Detection That Uses Half-Precision Data Type
这个例子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.
typesobelEdgeDetectionAlg
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 gradienth
and the vertical gradientv
of the input image by using two orthogonal filter kernelsmaskX
andmaskY
. 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 theimread
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 thesobelEdgeDetectionAlg
function by using thecodegen
command.
cfg = coder.config('mex'); cfg.TargetLang ='C++';cfg。GenerateReport = true;codegen-configcfg-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 namedsobelEdgeDetectionAlg_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);
生成静态的c++库
Use thecodegen
command to produces a C++ static library. By default, the generated library is located in the foldercodegen/lib/sobelEdgeDetectionAlg/
.
cfg = coder.config('lib'); cfg.TargetLang ='C++';cfg。GenerateReport = true;codegen-configcfg-args{imPacked,thresh}sobelEdgeDetectionAlg;
Code generation successful: To view the report, open('codegen/lib/sobelEdgeDetectionAlg/html/report.mldatx')
Inspect the Generated Function
typecodegen/lib/sobelEdgeDetectionAlg/sobelEdgeDetectionAlg.cpp
// // File: sobelEdgeDetectionAlg.cpp // // MATLAB Coder version : 5.4 // C/C++ source code generated on : 26-Feb-2022 10:44:25 // // Include Files #include "sobelEdgeDetectionAlg.h" #include "conv2MovingWindowSameCM.h" #include "rtwhalf.h" #include "sobelEdgeDetectionAlg_data.h" #include "sobelEdgeDetectionAlg_initialize.h" #include// 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(*(real16_T(*)[196608]) & img[196608], hv, h); coder::conv2MovingWindowSameCM(*(real16_T(*)[196608]) & 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 ( std::sqrt(static_cast (b_h * b_h + h1 * h1))); h[k] = b_h; edgeImg[k] = static_cast ((b_h > thresh) * 240U); } } // // File trailer for sobelEdgeDetectionAlg.cpp // // [EOF] //
See Also
Related Topics
- Floating-Point Numbers(Fixed-Point Designer)