Этот пример показывает, как создать исполняемый файл C из кода MATLAB®, который реализует простой фильтр Sobel, чтобы выполнить обнаружение ребра на изображениях. Исполняемый файл читает изображение из диска, применяет алгоритм фильтрации Sobel, и затем сохраняет измененный образ.
Пример показывает, как сгенерировать и изменить пример основная функция, которую можно использовать, когда вы создаете исполняемый файл.
Чтобы завершить этот пример, установите следующие продукты:
MATLAB
MATLAB Coder™
Компилятор C (для большинства платформ, компилятор C по умолчанию предоставляется MATLAB). Для списка поддерживаемых компиляторов см. Поддерживаемые Компиляторы.
Можно использовать mex -setup
, чтобы изменить компилятор по умолчанию. См. Компилятор Значения по умолчанию Изменения (MATLAB).
Файлы, которые вы используете в этом примере:
FileName | FileType | Описание |
---|---|---|
sobel.m | Функциональный код | Реализация MATLAB алгоритма фильтрации Sobel. sobel.m берет изображение (представленный как двойная матрица) и пороговое значение как входные параметры. Алгоритм обнаруживает ребра в изображении (на основе порогового значения). sobel.m возвращает измененное изображение, отображающее ребра. |
hello.jpg | Файл изображения | Отобразите это, фильтр Sobel изменяет. |
Скопировать файлы в качестве примера в локальную рабочую папку:
Создайте локальную рабочую папку. Например, c:\coder\edge_detection
.
Перейдите к рабочей папке.
Скопируйте файлы sobel.m
и hello.jpg
от папки sobel
в качестве примера до вашей рабочей папки.
copyfile(fullfile(docroot, 'toolbox', 'coder', 'examples', 'sobel'))
Считайте оригинальное изображение в матрицу MATLAB и отобразите его.
im = imread('hello.jpg');
Отобразите изображение как основание для сравнения с результатом фильтра Sobel.
image(im);
Алгоритм фильтрации Sobel работает с полутоновыми изображениями. Преобразуйте цветное изображение в эквивалентное полутоновое изображение с нормированными значениями (0.0 для черного цвета, 1.0 для белого).
gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
Чтобы запустить функцию MATLAB для фильтра Sobel, передайте матрицу полутонового изображения gray
и пороговое значение к функциональному sobel
. Этот пример использует 0.7 для порогового значения.
edgeIm = sobel(gray, 0.7);
Чтобы отобразить измененное изображение, переформатируйте матричный edgeIm
с функциональным repmat
так, чтобы можно было передать его команде image
.
im3 = repmat(edgeIm, [1 1 3]); image(im3);
Протестировать тот сгенерированный код функционально эквивалентно оригинальному коду MATLAB и этому, ошибки времени выполнения не происходят, генерируют MEX-функцию.
codegen -report sobel
codegen
генерирует MEX-функцию под названием sobel_mex
в текущей рабочей папке.
Чтобы запустить MEX-функцию для фильтра Sobel, передайте матрицу полутонового изображения gray
и пороговое значение к функциональному sobel_mex
. Этот пример использует 0.7 для порогового значения.
edgeImMex = sobel_mex(gray, 0.7);
Чтобы отобразить измененное изображение, переформатируйте матричный edgeImMex
с функциональным repmat
так, чтобы можно было передать его команде image
.
im3Mex = repmat(edgeImMex, [1 1 3]); image(im3Mex);
Это изображение эквивалентно, изображение создало использование функции MATLAB.
Несмотря на то, что можно записать пользовательскую основную функцию для приложения, пример, основная функция обеспечивает шаблон, чтобы помочь вам включить сгенерированный код.
Сгенерировать пример основная функция для фильтра Sobel:
Создайте объект настройки для статической библиотеки C.
cfg = coder.config('lib');
Для объектов настройки для исходного кода C/C++, статических библиотек, динамических библиотек и исполняемых файлов, установка GenerateExampleMain
управляет генерацией примера основная функция. Установка установлена в 'GenerateCodeOnly'
по умолчанию, который генерирует пример основная функция, но не компилирует ее. В данном примере не изменяйте значение установки GenerateExampleMain
.
Сгенерируйте статическую библиотеку C с помощью объекта настройки.
codegen -report -config cfg sobel
Сгенерированные файлы для статической библиотеки находятся в папке codegen/lib/sobel
. Пример основные файлы находится в подпапке codegen/lib/sobel/examples
.
Не изменяйте файлы 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
:
Удалите объявления void(argc)
и (void)argv
.
Объявите, что переменная filename
содержит имя двоичного файла, содержащего данные о полутоновом изображении.
const char *filename;
Объявите, что переменная threshold
содержит пороговое значение.
double threshold;
Объявите, что переменная fd
содержит адрес данных о полутоновом изображении, в которых считывает приложение из filename
.
FILE *fd;
Добавьте оператор if
, который проверяет на три аргумента.
if (argc != 3) { printf("Expected 2 arguments: filename and threshold\n"); exit(-1); }
Присвойте входной параметр argv[1]
для файла, содержащего данные о полутоновом изображении к filename
.
filename = argv[1];
Присвойте входной параметр argv[2]
для порогового значения к threshold
, преобразовав вход от строки до числового дважды.
threshold = atof(argv[2]);
Откройте файл, содержащий данные о полутоновом изображении, имя которых задано в filename
. Присвойте адрес потока данных к fd
.
fd = fopen(filename, "rb");
Чтобы проверить, что исполняемый файл может открыть filename
, запишите if
- оператор, который выходит из программы, если значением fd
является NULL
.
if (fd == NULL) { exit(-1); }
Замените вызов функции для main_sobel
путем вызова main_sobel
с входными параметрами fd
и threshold
.
main_sobel(fd, threshold);
Закройте файл полутонового изображения после вызова sobel_terminate
.
fclose(fd);
В примере основной файл функциональный argInit_d1024xd1024_real_T
создает динамически выделенный массив переменного размера (emxArray) для изображения, которое вы передаете фильтру Sobel. Эта функция инициализирует emxArray к размеру по умолчанию и элементам emxArray к 0. Это возвращает инициализированный emxArray.
Для приложения фильтра Sobel измените функцию, чтобы считать данные о полутоновом изображении из двоичного файла в emxArray.
В функциональном argInit_d1024xd1024_real_T
:
Замените входной параметр void
на аргумент FILE *fd
. Эта переменная указывает на данные о полутоновом изображении, что функция читает в.
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd)
Измените значения переменной iv2
, чтобы совпадать с размерностями матрицы полутонового изображения gray
. iv2
содержит значения размера для размерностей emxArray, который создает argInit_d1024xd1024_real_T
.
static int iv2[2] = { 484, 648 };
MATLAB хранит матричные данные в главном столбцом формате, в то время как C хранит матричные данные в главном строкой формате. Объявите размерности соответственно.
Задайте переменную element
, чтобы сдержать значения, считанные из данных о полутоновом изображении.
double element;
Измените for
- построение цикла, чтобы считать точки данных из нормированного изображения в element
путем добавления команды fread
во внутренний for
- цикл.
fread(&element, 1, sizeof(element), fd);
В for
- цикл, присвойте element
как набор значений для emxArray данных.
result->data[b_j0 + result->size[0] * b_j1] = element;
Функция MATLAB интерфейсы sobel.m
с массивами MATLAB, но Sobel фильтруют интерфейсы приложения с двоичными файлами.
Чтобы сохранить образ, измененный алгоритмом фильтрации Sobel к двоичному файлу, создайте функциональный saveImage
. Функциональный saveImage
записывает данные от emxArray в двоичный файл. Это использует конструкцию, которая подобна тому, используемому функциональным argInit_d1024xd1024_real_T
.
В файле main.c
:
Задайте функциональный saveImage
, который берет адрес emxArray edgeImage
как вход и вывел тип пусто.
static void saveImage(emxArray_uint8_T *edgeImage) { }
Задайте переменные b_j0
и b_j1
как, они заданы в функциональном argInit_d1024xd1024_real_T
.
int b_j0; int b_j1;
Задайте переменную element
, чтобы хранить данные, считанные из emxArray.
uint8_T element;
Откройте двоичный файл edge.bin
для записи измененного изображения. Присвойте адрес edge.bin
к FILE *fd
.
FILE *fd = fopen("edge.bin", "wb");
Чтобы проверить, что исполняемый файл может открыть edge.bin
, запишите if
- оператор, который выходит из программы, если значением fd
является NULL
.
if (fd == NULL) { exit(-1); }
Запишите вложенный 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++) { } }
Во внутреннем for
- цикл, присвойте значения от измененных данных изображения до element
.
element = edgeImage->data[b_j0 + edgeImage->size[0] * b_j1];
После присвоения для element
запишите значение от element
до файла edge.bin
.
fwrite(&element, 1, sizeof(element), fd);
После for
- построение цикла, закройте fd
.
fclose(fd);
В примере основная функция функциональный 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
:
Замените входные параметры к функции с аргументами FILE *fd
и double threshold
.
static void main_sobel(FILE *fd, double threshold)
Передайте входной параметр fd
вызову функции для argInit_d1024xd1024_real_T
.
originalImage = argInit_d1024xd1024_real_T(fd);
Замените вход порогового значения в вызове функции к sobel
с threshold
.
sobel(originalImage, threshold, edgeImage);
После вызова функционального sobel
вызовите функциональный saveImage
с входом edgeImage
.
saveImage(edgeImage);
Чтобы совпадать с изменениями, которые вы внесли в функциональные определения, внесите следующие изменения в объявления функции:
Измените вход функционального *argInit_d1024xd1024_real_T
к FILE *fd
.
static emxArray_real_T *argInit_d1024xd1024_real_T(FILE *fd);
Измените входные параметры функционального main_sobel
к FILE *fd
и double threshold
.
static void main_sobel(FILE *fd, double threshold);
Добавьте функциональный saveImage
.
static void saveImage(emxArray_uint8_T *edgeImage);
Для функций ввода/вывода, которые вы используете в main.c
, добавьте заголовочный файл stdio.h
во включенный список файлов.
#include <stdio.h>
main.c
Перейдите к рабочей папке, если вы не находитесь в настоящее время в ней.
Создайте объект настройки для независимого исполняемого файла C.
cfg = coder.config('exe');
Сгенерируйте независимый исполняемый файл C для фильтра Sobel с помощью объекта настройки и измененной основной функции.
codegen -report -config cfg sobel main.c main.h
По умолчанию, если вы запускаете MATLAB на платформе Windows®, исполняемый sobel.exe
сгенерирован в текущей рабочей папке. Если при запуске MATLAB на платформе кроме Windows, расширение файла является соответствующим расширением для той платформы. По умолчанию код, сгенерированный для исполняемого файла, находится в папке codegen/exe/sobel
.
Создайте матрицу MATLAB gray
, если это не находится в настоящее время в вашем рабочем пространстве MATLAB:
im = imread('hello.jpg');
gray = (0.2989 * double(im(:,:,1)) + 0.5870 * double(im(:,:,2)) + 0.1140 * double(im(:,:,3)))/255;
Запишите матричный gray
в двоичный файл с помощью команд fwrite
и fopen
. Приложение читает в этом двоичном файле.
fid = fopen('gray.bin', 'w'); fwrite(fid, gray, 'double'); fclose(fid);
Запустите исполняемый файл, передав ему файл gray.bin
и пороговое значение 0.7.
Запускать пример в MATLAB на платформе Windows:
system('sobel.exe gray.bin 0.7');
Исполняемый файл генерирует файл edge.bin
.
Считайте файл edge.bin
в матрицу MATLAB edgeImExe
с помощью команд fread
и fopen
.
fd = fopen('edge.bin', 'r'); edgeImExe = fread(fd, size(gray), 'uint8'); fclose(fd);
Передайте матричный edgeImExe
функциональному repmat
и отобразите изображение.
im3Exe = repmat(edgeImExe, [1 1 3]); image(im3Exe);
Изображение совпадает с изображениями из MATLAB и MEX-функций.