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

В этом примере показано, как создать исполняемый файл 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 File main.c

Скопируйте основные файлы примера

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

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

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

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

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

Этот пример изменяет файл main.c так что приложение фильтра Собеля:

  • Считывает в полутоновом изображении из двоичного файла.

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

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

Измените Function main

Измените функцию 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);

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

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

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

Для приложения фильтра Sobel измените функцию, чтобы считать данные полутонового изображения из двоичного файла в 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-цикл конструкция, чтобы считать точки данных из нормализованного изображения в element путем добавления fread команда на внутренний for-цикл.

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

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

 Измененные функциональные argInit_d1024xd1024_real_T инициализации

Запишите Function saveImage

Функция 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-цикл создайте так же, как в функции 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-цикл, присвойте значения из измененных данных изображения element.

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

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

    fclose(fd);

 Function saveImage

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

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

Для приложения фильтра Sobel измените функцию 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

Сгенерируйте приложение Sobel Filter

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

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

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

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

По умолчанию, если MATLAB запускается в Windows® platform, исполняемый файл 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-функций.

Похожие темы