Этот пример показывает, как сгенерировать автономную библиотеку 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-функцию с помощью команды 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;
Передайте нормализованное изображение и пороговое значение.
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] */