В этом примере показано, как создать исполняемый файл C из кода MATLAB®, который реализует простой фильтр Sobel, чтобы выполнить обнаружение ребра на изображениях. Исполняемый файл читает изображение из диска, применяет алгоритм фильтрации Sobel, и затем сохраняет модифицированный образ.
Пример показывает, как сгенерировать и изменить пример основная функция, которую можно использовать, когда вы создаете исполняемый файл.
Чтобы завершить этот пример, установите следующие продукты:
MATLAB
MATLAB Coder™
Компилятор C (для большинства платформ, компилятор C по умолчанию предоставляется MATLAB). Для списка поддерживаемых компиляторов см. Поддерживаемые Компиляторы.
Можно использовать mex -setup
изменить компилятор по умолчанию. См. Компилятор Значения по умолчанию Изменения.
Файлы, которые вы используете в этом примере:
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
isNull
.
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;
Модифицированная Функция Инициализации argInit_d1024xd1024_real_T
Функция 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
isNull
.
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
в двоичный файл с помощью fopen
и fwrite
команды. Приложение читает в этом двоичном файле.
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
использование fopen
и fread
команды.
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-функций.