Граничное обнаружение на изображениях

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

О функции sobel

Функция sobel.m берет изображение (представленный как двойная матрица) и пороговое значение и возвращает изображение с обнаруженными краями (на основе порогового значения).

type sobel
% edgeImage = sobel(originalImage, threshold)
% Sobel edge detection. Given a normalized image (with double values)
% return an image where the edges are detected w.r.t. threshold value.
function edgeImage = sobel(originalImage, threshold) %#codegen
assert(all(size(originalImage) <= [1024 1024]));
assert(isa(originalImage, 'double'));
assert(isa(threshold, 'double'));

k = [1 2 1; 0 0 0; -1 -2 -1];
H = conv2(double(originalImage),k, 'same');
V = conv2(double(originalImage),k','same');
E = sqrt(H.*H + V.*V);
edgeImage = uint8((E > threshold) * 255);

Сгенерируйте MEX-функцию

Сгенерируйте MEX-функцию с помощью команды codegen.

codegen sobel

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

Читайте в оригинальном изображении

Используйте стандартную команду imread.

im = imread('hello.jpg');
image(im);

Преобразуйте изображение в полутоновую версию

Преобразуйте цветное изображение (показанный выше) к эквивалентному полутоновому изображению с нормализованными значениями (0.0 для черного цвета, 1.0 для белого).

gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;

Запустите MEX-функцию (фильтр Sobel)

Передайте нормализованное изображение и пороговое значение.

edgeIm = sobel_mex(gray, 0.7);

Отобразите результат

im3 = repmat(edgeIm, [1 1 3]);
image(im3);

Сгенерируйте автономный код С

codegen -config coder.config('lib') sobel

Используя codegen с -config coder.config('lib') опция производит автономную библиотеку C. По умолчанию код, сгенерированный для библиотеки, находится в папке codegen/lib/sobel/.

Осмотрите сгенерированную функцию

type codegen/lib/sobel/sobel.c
/*
 * File: sobel.c
 *
 * MATLAB Coder version            : 4.1
 * C/C++ source code generated on  : 21-Aug-2018 23:29:14
 */

/* Include Files */
#include "sobel.h"
#include "sobel_emxutil.h"
#include "sqrt.h"
#include "conv2.h"

/* Function Definitions */

/*
 * Arguments    : const emxArray_real_T *originalImage
 *                double threshold
 *                emxArray_uint8_T *edgeImage
 * Return Type  : void
 */
void sobel(const emxArray_real_T *originalImage, double threshold,
           emxArray_uint8_T *edgeImage)
{
  emxArray_real_T *H;
  emxArray_real_T *V;
  int i0;
  int loop_ub;
  emxInit_real_T(&H, 2);
  emxInit_real_T(&V, 2);

  /*  edgeImage = sobel(originalImage, threshold) */
  /*  Sobel edge detection. Given a normalized image (with double values) */
  /*  return an image where the edges are detected w.r.t. threshold value. */
  conv2(originalImage, H);
  b_conv2(originalImage, V);
  i0 = H->size[0] * H->size[1];
  loop_ub = H->size[0] * H->size[1];
  emxEnsureCapacity_real_T(H, loop_ub);
  loop_ub = i0 - 1;
  for (i0 = 0; i0 <= loop_ub; i0++) {
    H->data[i0] = H->data[i0] * H->data[i0] + V->data[i0] * V->data[i0];
  }

  emxFree_real_T(&V);
  b_sqrt(H);
  i0 = edgeImage->size[0] * edgeImage->size[1];
  edgeImage->size[0] = H->size[0];
  edgeImage->size[1] = H->size[1];
  emxEnsureCapacity_uint8_T(edgeImage, i0);
  loop_ub = H->size[0] * H->size[1];
  for (i0 = 0; i0 < loop_ub; i0++) {
    edgeImage->data[i0] = (unsigned char)((H->data[i0] > threshold) * 255U);
  }

  emxFree_real_T(&H);
}

/*
 * File trailer for sobel.c
 *
 * [EOF]
 */
Была ли эта тема полезной?