Main Content

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 gradienthand the vertical gradientvof the input image by using two orthogonal filter kernelsmaskXandmaskY. 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 theimreadfunction to read the images.imreadrepresents 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 thesobelEdgeDetectionAlgfunction by using thecodegencommand.

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,codegengenerates a MEX function namedsobelEdgeDetectionAlg_mexin 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 thecodegencommand 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