Используйте пример C основной в приложении

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

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

Необходимые условия

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

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

Файлы, которые вы используете в этом примере:

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

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

 Содержимое hello.jpg

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

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

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

  3. Скопируйте файлы sobel.m и hello.jpg от папки sobel в качестве примера к вашей рабочей папке.

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

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

  1. Считайте оригинальное изображение в матрицу MATLAB и отобразите его.

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

    image(im);

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

    gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
  4. Чтобы запустить функцию MATLAB для фильтра Sobel, передайте матрицу полутонового изображения 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-функцию для фильтра Sobel, передайте матрицу полутонового изображения 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

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

Сгенерировать пример основная функция для фильтра Sobel:

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

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

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

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

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

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

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

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

  • Сохраняет модифицированный образ к двоичному файлу.

Измените Функциональное основное

Измените функциональный 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 isNull.

    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) для изображения, которое вы передаете фильтру Sobel. Эта функция инициализирует 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

Запишите Функцию saveImage

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

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

В файле main.c:

  1. Задайте функциональный saveImage это берет адрес emxArray edgeImage как вход и вывел тип пусто.

    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 isNull.

    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);

 Функция 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.

  • Передайте данные алгоритму фильтрации Sobel с пороговым значением 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

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

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

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

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

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

Запустите приложение фильтра Sobel

  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-функций.

Похожие темы