Сгенерируйте код для обнаружения ребра Sobel, которое использует тип данных полуточности

В этом примере показано, как сгенерировать автономную библиотеку C++ от функции MATLAB®, которая выполняет обнаружение ребра Sobel изображений при помощи чисел с плавающей точкой полуточности. Алгоритм ребра Sobel принимает изображение, которое представлено как матрица и возвращает изображение, подчеркивая высокие пространственные области частоты, которые соответствуют ее ребрам. Этот пример также показывает, как протестировать genenrated код при помощи MEX-функции.

Алгоритм обнаружения ребра Sobel

В алгоритме обнаружения ребра 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, чтобы найти области изображения, которые соответствуют ребрам.

Считайте изображения и упакуйте данные в RGBA упакованный упорядоченный по столбцам порядок

Используйте imread функционируйте, чтобы считать изображения. imread представляет каналы RGB изображения с целыми числами, один для каждого пикселя. Целые числа лежат в диапазоне от 0 до 255. Просто кастинг входных параметров к половине типа может привести к переполнению во время сверток. Чтобы избежать этой проблемы, масштабируйте изображения к значениям между 0 и 1.

im = imread('peppers.png');
figure();
image(im);
imPacked = half(im)/255;
thresh = half(100)/255;

Сгенерируйте MEX

Сгенерируйте 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 и отображение обнаруженное ребро

Прежде, чем сгенерировать Код С++, необходимо сначала протестировать MEX-функцию в среде MATLAB, чтобы убедиться, что это функционально эквивалентно оригинальному коду MATLAB и что никакие ошибки времени выполнения не происходят. По умолчанию, codegen генерирует MEX-функцию под названием sobelEdgeDetectionAlg_mex в текущей папке. Это позволяет вам тестировать код MATLAB и MEX-функцию и сравнивать результаты.

out_disp = sobelEdgeDetectionAlg_mex(imPacked,thresh);
figure();
imagesc(out_disp);

Сгенерируйте статическую библиотеку C++

Используйте 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]
//

Смотрите также

| |

Похожие темы