exponenta event banner

Использование основного примера C в приложении

В этом примере показано, как построить исполняемый файл C из кода MATLAB ®, который реализует простой фильтр Собеля для обнаружения краев изображений. Исполняемый файл считывает изображение с диска, применяет алгоритм фильтрации Собеля, а затем сохраняет измененное изображение.

В примере показано, как создать и изменить пример основной функции, которую можно использовать при построении исполняемого файла.

Предпосылки

Чтобы завершить этот пример, установите следующие продукты:

Создание папки и копирование соответствующих файлов

В этом примере используются следующие файлы:

Имя файлаТип файлаОписание
sobel.mКод функцииРеализация MATLAB алгоритма фильтрации Собеля. sobel.m принимает изображение (представленное в виде двойной матрицы) и пороговое значение в качестве входных данных. Алгоритм обнаруживает края в изображении (на основе порогового значения). sobel.m возвращает измененное изображение, отображающее края.
hello.jpgФайл изображенияИзображение, которое изменяет фильтр Собеля.

 Содержимое файла sobel.m

 Содержимое файла hello.jpg

Чтобы скопировать файлы примеров в локальную рабочую папку:

  1. Создайте локальную рабочую папку. Например, c:\coder\edge_detection.

  2. Перейдите в рабочую папку.

  3. Копировать файлы sobel.m и hello.jpg из папки примеров sobel в рабочую папку.

    copyfile(fullfile(docroot, 'toolbox', 'coder', 'examples', 'sobel'))

Запустить фильтр Собеля на изображении

  1. Прочитайте исходное изображение в матрице MATLAB и отобразите его.

    im = imread('hello.jpg');
  2. Отображение изображения в качестве основы для сравнения с результатом фильтра Собеля.

    image(im);

  3. Алгоритм фильтрации Собеля работает на изображениях в градациях серого. Преобразование цветного изображения в эквивалентное изображение в оттенках серого с нормализованными значениями (0,0 для черного, 1,0 для белого).

    gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
  4. Чтобы запустить функцию MATLAB для фильтра Собеля, передайте матрицу изображения в градациях серого gray и пороговое значение функции sobel. В этом примере для порогового значения используется значение 0,7.

    edgeIm = sobel(gray, 0.7);
  5. Чтобы отобразить измененное изображение, переформатируйте матрицу edgeIm с функцией repmat чтобы вы могли передать его в image команда.

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

Создание и тестирование функции MEX

  1. Чтобы проверить, что сгенерированный код функционально эквивалентен исходному коду MATLAB и что ошибки во время выполнения не возникают, создайте функцию MEX.

    codegen -report sobel

    codegen генерирует функцию MEX с именем sobel_mex в текущей рабочей папке.

  2. Чтобы запустить функцию MEX для фильтра Собеля, передайте матрицу изображения в градациях серого gray и пороговое значение функции sobel_mex. В этом примере для порогового значения используется значение 0,7.

    edgeImMex = sobel_mex(gray, 0.7);
  3. Чтобы отобразить измененное изображение, переформатируйте матрицу edgeImMex с функцией repmat чтобы вы могли передать его в image команда.

    im3Mex = repmat(edgeImMex, [1 1 3]);
    image(im3Mex);

    Это изображение совпадает с изображением, созданным с помощью функции MATLAB.

Создание примера основной функции для sobel.m

Несмотря на то, что можно создать пользовательскую основную функцию для приложения, пример основной функции предоставляет шаблон, помогающий включить созданный код.

Чтобы создать пример основной функции для фильтра Собеля:

  1. Создайте объект конфигурации для статической библиотеки C.

    cfg = coder.config('lib');

    Для объектов конфигурации для исходного кода C/C + +, статических библиотек, динамических библиотек и исполняемых файлов параметрGenerateExampleMain управляет созданием примера основной функции. Параметр имеет значение 'GenerateCodeOnly' по умолчанию, которая генерирует основную функцию примера, но не компилирует ее. Для этого примера не изменяйте значение GenerateExampleMain установка.

  2. Создайте статическую библиотеку C с помощью объекта конфигурации.

    codegen -report -config cfg sobel

Созданные файлы для статической библиотеки находятся в папке codegen/lib/sobel. Примеры основных файлов находятся во вложенной папке codegen/lib/sobel/examples.

 Содержимое основного файла примера main.c

Копирование основных файлов примеров

Не изменять файлы main.c и main.h в examples подпапка. В этом случае при регенерации кода кодер MATLAB не регенерирует основные файлы примера. Он предупреждает, что обнаруживает изменения в созданных файлах.

Копировать файлы main.c и main.h из папки codegen/lib/sobel/examples в другое место. В этом примере скопируйте файлы в текущую рабочую папку. Измените файлы в новом расположении.

Изменение созданной основной функции примера

В примере основной функции объявляются и инициализируются нулевые значения данных, включая динамически распределенные данные. Он вызывает функции точки входа с аргументами, равными нулю, но не использует значения, возвращаемые из функций точки входа.

Основная функция C должна соответствовать требованиям приложения. В этом примере основная функция примера изменяется в соответствии с требованиями приложения фильтра Собеля.

В этом примере изменяется файл main.c чтобы приложение фильтра Собеля:

  • Считывает изображение в оттенках серого из двоичного файла.

  • Применяет алгоритм фильтрации Собеля.

  • Сохранение измененного изображения в двоичном файле.

Изменение основной функции

Изменение функции main кому:

  • Примите файл, содержащий данные изображения в градациях серого и пороговое значение, в качестве входных аргументов.

  • Вызовите функцию main_sobel с адресом потока данных изображения в градациях серого и пороговым значением в качестве входных аргументов.

В функции main:

  1. Удалить объявления void(argc) и (void)argv.

  2. Объявить переменную filename для хранения имени двоичного файла, содержащего данные изображения в градациях серого.

    const char *filename;
  3. Объявить переменную threshold для сохранения порогового значения.

    double threshold;
  4. Объявить переменную fd для хранения адреса данных изображения в градациях серого, считываемых приложением из filename.

    FILE *fd;
  5. Добавить if оператор, который проверяет наличие трех аргументов.

    if (argc != 3) {
          printf("Expected 2 arguments: filename and threshold\n");
          exit(-1);
    }
  6. Назначение входного аргумента argv[1] для файла, содержащего данные изображения в градациях серого, filename.

    filename = argv[1];
  7. Назначение входного аргумента argv[2] для порогового значения для threshold, преобразуя входные данные из строки в числовой двойник.

    threshold = atof(argv[2]);
  8. Откройте файл, содержащий данные изображения в градациях серого, имя которого указано в filename. Назначение адреса потока данных fd.

    fd = fopen(filename, "rb");
  9. Проверка возможности открытия исполняемого файла filename, написать if- оператор, выходящий из программы, если значение fd является NULL.

    if (fd == NULL) {
       exit(-1);
    }
  10. Замените вызов функции для main_sobel путем вызова main_sobel с входными аргументами fd и threshold.

    main_sobel(fd, threshold);
  11. После вызова закройте файл изображения в градациях серого sobel_terminate.

    fclose(fd);

 Основная измененная функция

Измените функцию инициализации argInit_d1024xd1024_real_T

В примере основного файла функция argInit_d1024xd1024_real_T создает динамически выделяемый массив переменного размера (emxArray) для изображения, передаваемого в фильтр Собеля. Эта функция инициализирует размер emxArray по умолчанию, а элементы emxArray - 0. Он возвращает инициализированный emxArray.

Для приложения Sobel filter измените функцию, чтобы считать данные изображения в градациях серого из двоичного файла в emxArray.

В функции argInit_d1024xd1024_real_T:

  1. Заменить входной аргумент void с аргументом FILE *fd. Эта переменная указывает на данные изображения в градациях серого, считываемые функцией.

    static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
  2. Изменение значений переменной iv2 для соответствия размерам матрицы изображения в градациях серого gray. iv2 содержит значения размера для размеров emxArray, которые argInit_d1024xd1024_real_T создает.

    static int iv2[2] = { 484, 648 };

    MATLAB хранит матричные данные в формате «основной столбец», а C - в формате «основная строка». Объявите размеры соответствующим образом.

  3. Определение переменной element для хранения значений, считанных из данных изображения в градациях серого.

    double element;
  4. Изменить forконструкция -loop для считывания точек данных из нормализованного изображения в element путем добавления fread во внутреннюю for-луп.

    fread(&element, 1, sizeof(element), fd);
  5. Внутри for-loop, назначить element в качестве значения, установленного для данных emxArray.

    result->data[b_j0 + result->size[0] * b_j1] = element;

 Измененная функция инициализации argInit_d1024xd1024_real_T

Запишите значение параметра «Функция» (Function)

Функция MATLAB sobel.m интерфейсы с массивами MATLAB, но приложение фильтра Sobel взаимодействует с двоичными файлами.

Чтобы сохранить изображение, измененное алгоритмом фильтрации Собеля, в двоичный файл, создайте функцию saveImage. Функция saveImage записывает данные из массива emxArray в двоичный файл. Он использует конструкцию, аналогичную той, которая используется функцией argInit_d1024xd1024_real_T.

В файле main.c:

  1. Определение функции saveImage который принимает адрес emxArray edgeImage в качестве входа и имеет выходной тип void.

    static void saveImage(emxArray_uint8_T *edgeImage)
    {
    }
  2. Определение переменных b_j0 и b_j1 как они определены в функции argInit_d1024xd1024_real_T.

    int b_j0;
    int b_j1;
  3. Определение переменной element для хранения данных, считанных из массива emxArray.

    uint8_T element;
  4. Открытие двоичного файла edge.bin для записи измененного изображения. Назначить адрес edge.bin кому FILE *fd.

    FILE *fd = fopen("edge.bin", "wb");
  5. Проверка возможности открытия исполняемого файла edge.bin, написать if- оператор, выходящий из программы, если значение fd является NULL.

    if (fd == NULL) {
       exit(-1);
    }
  6. Написать вложенный forконструкция -loop, подобная конструкции в функции argInit_d1024xd1024_real_T.

    for (b_j0 = 0; b_j0 < edgeImage->size[0U]; b_j0++)
    {
        for (b_j1 = 0; b_j1 < edgeImage->size[1U]; b_j1++)
        {
        }
    }
  7. Внутри внутреннего for-loop, присвойте значения из измененных данных изображения element.

    element = edgeImage->data[b_j0 + edgeImage->size[0] * b_j1];
  8. После назначения для element, запишите значение из element в файл edge.bin.

    fwrite(&element, 1, sizeof(element), fd);
  9. После forконструкция -loop, закрыть fd.

    fclose(fd);

 Функция saveImage

Изменение функции main_sobel

В примере основной функции функция main_sobel создает массивы emxArrays для данных оттенков серого и измененных изображений. Он вызывает функцию argInit_d1024xd1024_real_T для инициализации массива emxArray для изображения в градациях серого. main_sobel передает как emxArrays, так и пороговое значение 0, что функция инициализации argInit_real_T возвращается к функции sobel. Когда функция main_sobel заканчивается, он отбрасывает результат функции sobel.

Для приложения Sobel filter измените функцию main_sobel кому:

  • Возьмите в качестве входных данных адрес изображения в градациях серого и пороговое значение.

  • Считывание данных с адреса с помощью argInit_d1024xd1024_real_T.

  • Передача данных в алгоритм фильтрации Собеля с пороговым значением threshold.

  • Сохранение результата с помощью saveImage.

В функции main_sobel:

  1. Заменить входные аргументы функции аргументами FILE *fd и double threshold.

    static void main_sobel(FILE *fd, double threshold)
  2. Передача входного аргумента fd к вызову функции для argInit_d1024xd1024_real_T.

    originalImage = argInit_d1024xd1024_real_T(fd);
  3. Замените пороговое значение, введенное в вызове функции, на sobel с threshold.

    sobel(originalImage, threshold, edgeImage);
  4. После вызова функции sobel, вызовите функцию saveImage со входом edgeImage.

    saveImage(edgeImage);

 Измененная функция main_sobel

Изменение объявлений функций

Чтобы соответствовать изменениям, внесенным в определения функций, внесите следующие изменения в объявления функций:

  1. Изменение ввода функции *argInit_d1024xd1024_real_T кому FILE *fd.

    static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
  2. Изменение входных данных функции main_sobel кому FILE *fd и double threshold.

    static void main_sobel(FILE *fd, double threshold);
  3. Добавление функции saveImage.

    static void saveImage(emxArray_uint8_T *edgeImage);

 Измененные объявления функций

Изменение файлов включения

Для функций ввода/вывода, используемых в main.c, добавьте файл заголовка stdio.h в список включенных файлов.

#include <stdio.h>

 Измененные файлы включения

Содержимое измененного файла main.c

 main.c

Создание приложения фильтра Собеля

  1. Перейдите в рабочую папку, если ее нет в данный момент.

  2. Создайте объект конфигурации для автономного исполняемого файла C.

    cfg = coder.config('exe');
  3. Создайте автономный исполняемый файл C для фильтра Собеля, используя объект конфигурации и измененную основную функцию.

    codegen -report -config cfg sobel main.c main.h

По умолчанию при работе с MATLAB на платформе Windows ® исполняемый файлsobel.exe создается в текущей рабочей папке. Если MATLAB выполняется на платформе, отличной от Windows, расширение файла является соответствующим расширением для этой платформы. По умолчанию код, созданный для исполняемого файла, находится в папке codegen/exe/sobel.

Запуск приложения Sobel Filter

  1. Создание матрицы MATLAB gray если он отсутствует в рабочей области MATLAB:

    im = imread('hello.jpg');
    gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
  2. Запись матрицы gray в двоичный файл с помощью fopen и fwrite команды. Приложение читает в этом двоичном файле.

    fid = fopen('gray.bin', 'w');
    fwrite(fid, gray, 'double');
    fclose(fid);
  3. Запустите исполняемый файл, передав ему файл gray.bin и пороговое значение 0,7.

    Для запуска примера в MATLAB на платформе Windows:

    system('sobel.exe gray.bin 0.7');

    Исполняемый файл генерирует файл edge.bin.

Отображение результирующего изображения

  1. Прочитать файл edge.bin в матрицу MATLAB edgeImExe с использованием fopen и fread команды.

    fd = fopen('edge.bin', 'r');
    edgeImExe = fread(fd, size(gray), 'uint8');
    fclose(fd);
  2. Передача матрицы edgeImExe к функции repmat и отобразить изображение.

    im3Exe = repmat(edgeImExe, [1 1 3]);
    image(im3Exe);

    Изображение соответствует изображениям из функций MATLAB и MEX.

Связанные темы