В этом примере показано, как использовать Coder™ MATLAB ® для создания кода C из файла MATLAB и развертывания приложения на цели ARM.
Пример считывает видеокадры с веб-камеры и обнаруживает лица в каждом из кадров с помощью алгоритма обнаружения лица Виолы-Джонса. Обнаруженные грани отображаются с ограничивающими прямоугольниками. Функция веб-камеры из «MATLAB Support Package for USB Webcams» и объект VideyPlayer из toolbox™ Computer Vision System используются для моделирования на хосте MATLAB. Эти две функции не поддерживают цель ARM, поэтому для развертывания используются функции чтения веб-камер и просмотра видео на основе OpenCV.
Целевой объект должен иметь библиотеки OpenCV версии 3.4.0 (построенные с GTK) и стандартный компилятор C++. Для развертывания использовалась Raspberry Pi 2 с операционной системой Raspbian Stretch. Пример должен работать на любой цели ARM.
В этом примере требуется лицензия кодера MATLAB.
Этот пример является функцией с основным корпусом в верхней части и вспомогательными подпрограммами в виде вложенных функций ниже.
function FaceDetectionARMCodeGenerationExample()
Для выполнения этого примера необходимо иметь доступ к компилятору C++ и настроить его с помощью команды «mex -setup c++». Дополнительные сведения см. в разделе Выбор компилятора C++.
Кодер MATLAB требует, чтобы код MATLAB имел форму функции для генерации кода C. Код основного алгоритма этого примера находится в функции FaceDetection ARMKernel.m. Функция берет изображение с веб-камеры в качестве входных данных. Функция выводит изображение с ограничивающей рамкой вокруг обнаруженных граней. Выходное изображение будет отображаться в окне просмотра видео. Чтобы узнать, как изменить код MATLAB, чтобы сделать его совместимым для генерации кода, см. пример Введение в генерацию кода с сопоставлением и регистрацией функций.
fileName = 'faceDetectionARMKernel.m';
Для автономного исполняемого целевого объекта MATLAB Coder требует создания C-файла, содержащего функцию с именем «main». В этом примере используется файл faceDetection ARMMain.c. Эта основная функция в этом файле выполняет следующие задачи:
Считывает видеокадры с веб-камеры
Передача видеокадров в алгоритм обнаружения лица
Отображение выходных кадров, содержащих ограничивающие рамки вокруг обнаруженных граней
Для моделирования на хосте MATLAB задачи, выполняемые в файле FaceDetenseARMMain.c, реализованы в faceDetection ARMMain.m
Для развертывания в ARM в этом примере реализована функция чтения веб-камер с использованием функций OpenCV. Он также реализует средство просмотра видео, используя функции OpenCV. Эти функции утилиты на основе OpenCV реализованы в следующих файлах:
helperOpenCVWebcam.hpp
helperOpenCVWebcam.cpp
helperOpenCVVideoViewer.cpp
helperOpenCVVideoViewer.hpp
Для моделирования на хосте MATLAB в примере используется функция веб-камеры из «MATLAB Support Package for USB Webcams» и объект VideyPlayer из панели инструментов Computer Vision System. Запустите моделирование на хосте MATLAB, введя FaceDetection ARMMain в командной строке MATLAB ®.
В этом примере необходимо установить библиотеки OpenCV 3.4.0 на целевой объект ARM. Для просмотра видео требуется построить библиотеку highqui в OpenCV с GTK для цели ARM.
Выполните действия для загрузки и сборки OpenCV 3.4.0 на Raspberry Pi 2 с предустановленным Raspbian Stretch. Перед началом создания OpenCV необходимо обновить системное микропрограммное обеспечение или установить другие средства и пакеты разработчика.
Отключить INSTALL_C_EXAMPLES из-за: https://github.com/opencv/opencv/issues/5851
Отключить ENABLE_PRECOMPILED_HEADERS из-за: https://github.com/opencv/opencv/issues/9942
$ wget -O opencv-3.4.0.zip https://github.com/opencv/opencv/archive/3.4.0.zip
$ unzip opencv-3.4.0.zip
$ cd opencv-3.4.0
$ mkdir сборка
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=OFF -D BUILD_EXAMPLES=ON -D WITH_GTK=ON -D WITH_FFMPEG=OFF -D ENABLE_PRECOMPILED_HEADERS=OFF..
Для компиляции и установки OpenCV необходимо выполнить следующие действия:
$ make
$ sudo сделать установку
Для официального развертывания примера библиотеки OpenCV были установлены в следующий каталог на Raspberry Pi 2:
/usr/local/lib
и соответствующие заголовки были помещены в
/usr/local/include
Создайте объект конфигурации генерации кода для вывода EXE.
codegenArgs = createCodegenArgs();
Вызовите команду codegen.
fprintf('-> Generating Code (it may take a few minutes) ....\n'); codegen(codegenArgs{:}, fileName); % During code generation, all dependent file information is stored in a mat % file named buildInfo.mat.
-> Generating Code (it may take a few minutes) .... Code generation successful.
Используйте сведения о построении, хранящиеся в buildInfo.mat, чтобы создать zip-папку с помощью packNGo.
fprintf('-> Creating zip folder (it may take a few minutes) ....\n'); bInfo = load(fullfile('codegen','exe','faceDetectionARMKernel','buildInfo.mat')); packNGo(bInfo.buildInfo, {'packType', 'hierarchical', ... 'fileName', 'faceDetectionARMKernel'}); % The generated zip folder is faceDetectionARMKernel.zip
-> Creating zip folder (it may take a few minutes) ....
Unzip faceDetenseARMKernel.zip в папку с именем FaceDetenseARM. Распакуйте все файлы и удалите ZIP-файлы.
packngoDir = hUnzipPackageContents();
Warning: Directory already exists.
Makefile, faceDetectionARMMakefile.mk, представленный в этом примере, написан для Raspberry PI 2 с определенными флагами оптимизации. Makefile был написан для работы с GCC в среде Linux и с библиотеками OpenCV, расположенными в/usr/local/lib. Makefile можно обновить в соответствии с целевой конфигурацией. Скопируйте файл Makefile в папку проекта.
copyfile('faceDetectionARMMakefile.mk', packngoDir); % Also move the file containing the main function in the top level folder. copyfile('faceDetectionARMMain.c', packngoDir); % For simplicity, make sure the root directory name is matlab. setRootDirectory(packngoDir);
Развертывание проекта на ARM:
disp('Follow these steps to deploy your project on ARM');
Follow these steps to deploy your project on ARM
Перенесите папку проекта FaceDetection ARM в цель ARM с помощью предпочтительного средства передачи файлов. Поскольку Raspberry Pi 2 (с Raspbian Stretch) уже имеет SSH-сервер, можно использовать SFTP для передачи файлов с хоста на конечный объект.
Для официального развертывания этого примера клиент FileZilla SFTP был установлен на хост-машине и папка проекта была перенесена с хоста в папку/home/pi/FaceDetenseARM на Raspberry Pi.
disp('Step-1: Transfer the folder ''FaceDetectionARM'' to your ARM target');
Step-1: Transfer the folder 'FaceDetectionARM' to your ARM target
Запустите make-файл для создания исполняемого файла в ARM. Для Raspberry Pi 2 (с Raspbian Stretch) откройте оболочку linux и cd to/home/pi/FaceDetenseARM. Создайте исполняемый файл с помощью следующей команды:
сделать -f faceDetection ARMMakefile
Команда создает исполняемый файл FaceDetenseARMKernel.
disp('Step-2: Build the executable on ARM using the shell command: make -f faceDetectionARMMakefile.mk');
Step-2: Build the executable on ARM using the shell command: make -f faceDetectionARMMakefile.mk
Запустите исполняемый файл, созданный на приведенном выше шаге. Для Raspberry Pi 2 (с Raspbian Stretch) используйте следующую команду в окне оболочки:
./faceDetenseARMKernel
Убедитесь, что вы подключены к Raspberry Pi с помощью оконного менеджера, а не только через терминал командной строки, чтобы избежать ошибок, связанных с GTK. Это необходимо для отображения окна отслеживания.
Чтобы закрыть средство просмотра видео во время выполнения исполняемого файла на Raspberry Pi2, щелкните средство просмотра видео и нажмите клавишу escape.
disp('Step-3: Run the executable on ARM using the shell command: ./faceDetectionARMKernel');
Step-3: Run the executable on ARM using the shell command: ./faceDetectionARMKernel
% Configure coder to create executable. Use packNGo at post code % generation stage. function codegenArgs = createCodegenArgs() % Create arguments required for code generation. % First - create configuration object % % For standalone executable a main C function is required. The % faceDetectionARMMain.c created for this example is compatible % with the content of the file faceDetectionARMKernel.m mainCFile = 'faceDetectionARMMain.c'; % Include helper functions camCPPFile = 'helperOpenCVWebcam.cpp'; viewerCPPFile = 'helperOpenCVVideoViewer.cpp'; % Handle path with space if contains(mainCFile, ' ') mainCFile = ['"' mainCFile '"']; camCPPFile = ['"' camCPPFile '"']; viewerCPPFile = ['"' viewerCPPFile '"']; end % Create configuration object cfg = coder.config('exe'); cfg.CustomSource = sprintf('%s\n%s\n%s',mainCFile,camCPPFile,viewerCPPFile); cfg.CustomInclude = pwd; % Set production hardware to ARM to generate ARM compatible portable code cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM Cortex'; cfg.EnableOpenMP = false; % Create input arguments inRGB_type = coder.typeof(uint8(0),[480 640 3]); % Use '-c' option to generate C code without calling C++ compiler. codegenArgs = {'-config', cfg, '-c', '-args', {inRGB_type}}; end % Unzip the packaged zip file function packngoDir = hUnzipPackageContents() packngoDirName = 'FaceDetectionARM'; % create packngo directory mkdir(packngoDirName); % get the name of the single zip file generated by packngo zipFile = dir('*.zip'); assert(numel(zipFile)==1); unzip(zipFile.name,packngoDirName); % unzip internal zip files created in hierarchical packNGo zipFileInternal = dir(fullfile(packngoDirName,'*.zip')); for i=1:numel(zipFileInternal) unzip(fullfile(packngoDirName,zipFileInternal(i).name), ... packngoDirName); end % delete internal zip files delete(fullfile(packngoDirName,'*.zip')); packngoDir = packngoDirName; end % Set root directory as matlab function setRootDirectory(packngoDir) dirList = dir(packngoDir); if isempty(find(ismember({dirList.name},'matlab'), 1)) % root directory is not matlab. Change it to matlab for i=1:length(dirList) thisDir = fullfile(packngoDir,dirList(i).name, 'toolbox', 'vision'); if isfolder(thisDir) % rename the dir movefile(fullfile(packngoDir,dirList(i).name), ... fullfile(packngoDir,'matlab')); break; end end end end
end