В этом примере показано, как сгенерировать автономную библиотеку C++ от функции MATLAB®, которая выполняет обнаружение ребра Sobel изображений при помощи чисел с плавающей точкой полуточности. Алгоритм ребра Sobel принимает изображение, которое представлено как матрица и возвращает изображение, подчеркивая высокие пространственные области частоты, которые соответствуют ее ребрам. Этот пример также показывает, как протестировать genenrated код при помощи MEX-функции.
В алгоритме обнаружения ребра Sobel 2D пространственная операция градиента выполняется на полутоновом изображении. Эта операция подчеркивает высокие пространственные области частоты, которые соответствуют ребрам в изображении.
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
Алгоритм ребра Sobel вычисляет горизонтальный градиент h
и вертикальный градиент v
из входа отображают при помощи двух ортогональных ядер фильтра maskX
и maskY
. После операции фильтрации алгоритм вычисляет величину градиента и применяет threhold, чтобы найти области изображения, которые соответствуют ребрам.
Используйте imread
функционируйте, чтобы считать изображения. imread
представляет каналы RGB изображения с целыми числами, один для каждого пикселя. Целые числа лежат в диапазоне от 0 до 255. Просто кастинг входных параметров к половине типа может привести к переполнению во время сверток. Чтобы избежать этой проблемы, масштабируйте изображения к значениям между 0 и 1.
im = imread('peppers.png');
figure();
image(im);
imPacked = half(im)/255;
thresh = half(100)/255;
Сгенерируйте MEX-функцию C++ для sobelEdgeDetectionAlg
функция при помощи codegen
команда.
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').
Прежде, чем сгенерировать Код С++, необходимо сначала протестировать MEX-функцию в среде MATLAB, чтобы убедиться, что это функционально эквивалентно оригинальному коду MATLAB и что никакие ошибки времени выполнения не происходят. По умолчанию, codegen
генерирует MEX-функцию под названием sobelEdgeDetectionAlg_mex
в текущей папке. Это позволяет вам тестировать код MATLAB и MEX-функцию и сравнивать результаты.
out_disp = sobelEdgeDetectionAlg_mex(imPacked,thresh); figure(); imagesc(out_disp);
Используйте codegen
команда к продуктам C++ статическая библиотека. По умолчанию сгенерированная библиотека расположена в папке 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').
type codegen/lib/sobelEdgeDetectionAlg/sobelEdgeDetectionAlg.cpp
// // File: sobelEdgeDetectionAlg.cpp // // MATLAB Coder version : 5.2 // C/C++ source code generated on : 26-Jan-2021 21:48:43 // // Include Files #include "sobelEdgeDetectionAlg.h" #include "conv2MovingWindowSameCM.h" #include "rtwhalf.h" #include "sobelEdgeDetectionAlg_data.h" #include "sobelEdgeDetectionAlg_initialize.h" #include <cmath> // Function Definitions // // sobelEdgeDetection Example MATLAB function for edge detection. // Copyright 2018 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<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] //
codegen
| coder.config
| half