В этом примере показано, как создать автономную библиотеку C++ из функции MATLAB ®, которая выполняет обнаружение краев изображений по Собелю с помощью чисел с плавающей запятой с полупрецизионной точностью. Алгоритм ребра Собеля принимает изображение, которое представлено в виде матрицы, и возвращает изображение, подчеркивающее области высокой пространственной частоты, которые соответствуют его краям. В этом примере также показано, как протестировать сгенерированный код с помощью функции MEX.
В алгоритме обнаружения краев Собеля выполняется операция 2-D пространственного градиента для изображения в градациях серого. Эта операция подчеркивает области высокой пространственной частоты, которые соответствуют краям в изображении.
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
Алгоритм ребра Собеля вычисляет горизонтальный градиент h и вертикальный градиент v входного изображения с использованием двух ортогональных ядер фильтров maskX и maskY. После операции фильтрации алгоритм вычисляет величину градиента и применяет пороговое значение для поиска областей изображения, которые соответствуют краям.
Используйте imread для чтения изображений. imread представляет RGB-каналы изображений с целыми числами, по одному для каждого пикселя. Целые числа находятся в диапазоне от 0 до 255. Простое приведение входных данных к половинному типу может привести к переполнению во время свертки. Чтобы избежать этой проблемы, масштабируйте изображения до значений от 0 до 1.
im = imread('peppers.png');
figure();
image(im);
imPacked = half(im)/255;
thresh = half(100)/255;

Создание функции C++ MEX для 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').
Перед созданием кода C++ необходимо сначала протестировать функцию 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