Используйте пример 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.

 Содержимое Примера Основной основной Файл. 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 является 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) для изображения, которое вы передаете фильтру 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 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 является 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);

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

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

    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 с помощью команд fread и fopen.

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

Похожие темы

Была ли эта тема полезной?