主要内容

用Packngo进行面部跟踪的代码

此示例显示了如何生成代码使用KLT算法的面部检测和跟踪Packngo功能示例。这Packngo.(MATLAB编码器)功能包中的所有相关文件在压缩的zip文件中,因此您可以在没有Matlab的另一个开发环境中重新定位,解压缩和重建项目。此示例还显示了如何为PackNgo内容创建Makefile,重建源文件,最后运行Matlab环境外的独立可执行文件。

此示例需要Matlab®Coder™许可证。

此示例是顶部和辅助程序的主体的函数嵌套功能以下。

功能FaceTrackingkltpackngoexample()

设置C ++编译器

要运行此示例,您必须访问C ++编译器,您必须使用'mex -setup c ++'命令配置它。有关更多信息,请参阅选择C ++编译器。如果在MATLAB主机上部署应用程序,请使用与用于构建OpenCV库的编译器兼容的C ++编译器。有关更多信息,请参阅用于使用OpenCV库的函数的便携式C代码

将算法的计算部分分解为单独的MATLAB函数

Matlab编码器需要MATLAB代码以函数的形式以生成C代码。此示例的主要算法的代码驻留在一个调用的函数中FaceTrackingkltpackngo_kernel.m.。此文件派生自使用KLT算法的面部检测和跟踪。要了解如何修改MATLAB代码以使其兼容代码生成,可以查看示例使用功能匹配和注册的代码生成简介

filename =.'faceTrackingkltpackngo_kernel.m';VisionDemo_dir = PWD;CurrentDir = PWD;%存储当前目录filename = fullfile(VisionDemo_dir,filename);

配置代码生成参数Packngo.

使用PackNgo函数调用在后代码生成阶段创建用于exe输出的代码生成配置对象。

codegenargs = createCodegenargs(VisionDemo_dir);

设置代码生成环境

更改输出目录名称。

codegenoutdir = fullfile(VisionDemo_dir,'codegen');mkdir(Codegenoutdir);

添加现有目录的路径以访问必要的文件。

currentPath = AddPath(VisionDemo_dir);pathcleanup = oncleanup(@()路径(currentPath));CD(Codegenoutdir);dirchange = oncleanup(@()cd(currentdir));

创建打包的zip文件

使用packngo函数调用调用codegen命令。

fprintf(' - >生成代码(可能需要几分钟).... \ n');Codegen(Codegenargs {:},文件名);
- >生成代码(可能需要几分钟)....代码生成成功。

请注意,您可以使用codegen命令而不是使用codegen命令,并使用代码生成项目使用Codegen.(MATLAB编码器)。使用packngo函数的后代码生成命令来创建zip文件。

构建独立可执行文件

将zip文件解压缩到新文件夹中。请注意,ZIP文件包含源文件,标题文件,库,包含构建信息对象,数据文件的MAT文件。UnzippackageContents.和其他辅助功能包含在附录中。

zipfilelocation = codegenoutdir;fprintf(' - >解压缩文件.... \ n');UnzipfolderLocation = UnzippackageContents(ZipFilelocation);
- >解压缩文件....

从模板makefile创建平台依赖makefile。

fprintf(' - >创建makefile .... \ n');[〜,fname,〜] = fileparts(文件名);makefilename = createmakefile(VisionDemo_dir,UnzipfolderLocation,fname);
- >创建makefile ....

创建构建项目并运行它所需的命令。

fprintf(' - >创建''build命令''和''运行命令''.... \ n');[BuildCommand,Runcommand] = CreateBuildandRunCommands(ZipFileLocation,......UnzipfolderLocation,makefilename,fname);
- >创建'build命令'和'运行命令'....

使用Build命令构建项目。

fprintf(' - >构建可执行.... \ n');buildexecutable(UnzipfolderLocation,BuildCommand);
- >构建可执行....

运行可执行文件并部署

运行可执行文件并验证它是否有效。

CD(UnzipfolderLocation);系统(Runcommand);

通过复制可执行文件和库文件,可以将应用程序部署在另一台计算机中。

Ispublishing =〜isempty(snapnow('得到'));如果〜ispublishing.%跳过将目录打印到HTML页面fprintf('可执行文件和库文件位于以下文件夹中:\ n%s \ n',unzipfolderlocation);fprintf('重新执行运行以下命令:\ n');fprintf('1。CD(''%s'')\ n',unzipfolderlocation);fprintf('2。系统('%s'')\ n',Runcommand);结尾

附录 - 辅助功能

%配置编码器以创建可执行文件。在邮政编码中使用packngo%代阶段。功能Codegenargs = CreateCodeNargs(folderFormainc)%创建代码生成所需的参数。独立可执行文件的%需要一个主C函数。main.c.为此示例创建的%与文件的内容兼容%Visionfacetrackingkltpackngo_kernel.m.maincfile = fullfile(folderformainc,'main.c');%处理空间的路径如果包含(maincfile,''maincfile = ['“'maincfile.'“'];结尾cfg = coder.config('可执行程序');cfg.postcodegencenmand ='packngo(buildinfo,''packtype'','shierarchical'');';cfg.customsource = maincfile;cfg.custominclude = folderformainc;cfg.enableopenmp = false;codegenargs = {'-config',cfg};结尾%创建一个文件夹并将packngo内容解压缩到其中。功能UnzipfolderLocation = UnzippackageContents(ZipFileLocation)%解压缩打包的zip文件。UnzipfolderLocationName ='unzippackngo';mkdir(UnzipfolderlocationName);%获取packngo生成的zip文件的名称。zipfile = dir('*。压缩');断言(Numel(Zipfile)== 1);解压缩(zipfile.name,UnzipfolderLocationName);%unzip内部zip文件在分层Packngo中创建。zipfileinternal = dir(fullfile(UnzipfolderLocationName,'*。压缩'));断言(Numel(Zipfileinternal)== 3);为了i = 1:numel(zipfileinternal)解压缩(fullfile(UnzipfolderlocationName,ZipfileInternal(i).name),......UnzipfolderLocationName);结尾UnzipfolderLocation = fullfile(zipfilelocation,UnzipfolderLocationName);结尾%从模板makefile中创建平台依赖makefile。采用%buildinfo获取有关工具链的信息。功能makefilename = createmakefile(VisionDemo_dir,UnzipfolderLocation,Fname)%从buildinfo创建makefile。binfo = load(fullfile(pwd,'codegen''可执行程序',fname,'buildinfo.mat'));LastDir = CD(UnzipfolderLocation);dircleanup = oncleanup(@()cd(lastdir));%获取包含工具箱/ vision子目录的根目录matlabdirname = getrootdirname(UnzipfolderLocation);%获得定义Horzcat_with_space = @(cellval)sprintf('%s',cellval {:});defs = horzcat_with_space(getdefines(binfo.buildinfo));%获取源文件列表如果ispc [〜,cfiles] =系统(['dir / s / b''*。C']);[〜,cppfiles] =系统(['dir / s / b''* .cpp']);别的[〜,cfiles] =系统(['寻找 。/ ''-名称 ''''*。C''']);[〜,cppfiles] =系统(['寻找 。/ ''-名称 ''''* .cpp'']);结尾cindx = strfind(cfiles,'。C');cppindx = strfind(cppfiles,'.cpp');srcfilesc = [];srcfilescpp = [];为了i = 1:长度(cindx)如果i == 1 startidx = 1;EndidX = Cindx(i);别的startidx = cindx(I-1)+1;EndidX = Cindx(i);结尾[〜,b,〜] = fileparts(cfiles(startidx:endidx));srcfilesc = [srcfilesc''B.'。C'];%#OK 结尾为了i = 1:长度(cppindx)如果i == 1 startidx = 1;EndIDX = CPPINDX(i);别的startidx = cppindx(i-1)+1;EndIDX = CPPINDX(i);结尾[〜,b,〜] = fileparts(cppfiles(startidx:endidx));srcfilescpp = [srcfilescpp''B.'.cpp'];%#OK 结尾srcfiles = [srcfilesc''srcfilescpp];%获得平台依赖名称如果Isunix.%Mac和Linuxtmf ='templatemakefilepackngo_unix';如果Ismac Archdir ='maci64';dllext ='迪拉布';别的archdir ='glnxa64';dllext ='所以';结尾别的tmf ='templatemakefilepackngo_win';archdir ='win64';dllext ='DLL';结尾百分比我们已经定义了,允许创建一个平台依赖makefile百分比从模板。FID = FOPEN(FullFile(VisionDemo_dir,TMF));filecontent = char(fread(fid)');fclose(FID);newfilecontent = regexprep(filecontent,......{'paste_arch''paste_ext''paste_defines''paste_srcfiles''paste_matlab'},......{Archdir,Dllext,Defs,Srcfiles,Matlabdirname});makefilename ='makefile';mk_name = fullfile(UnzipfolderLocation,makefilename);如果Isunix.如果(ISMAC)[状态,sysheaderpath] =系统('Xcode-Select-intret-path');断言(状态== 0,['无法获得系统的路径'......“使用''xcode-select-intret-path''的头文件'']);[状态,sdkpaths] =系统(['寻找 'DeBlank(SysheDerPath)......'-name''macosx * .sdk'']);断言(状态== 0,'找不到macosx sdk');%可能有多个SDKsdkpathcell = strsplit(sdkpaths,'\ n');为了Idx = 1:numel(sdkpathcell)如果〜isempty(sdkpathcell {idx})%选择不空的第一个。sdkpath = sdkpathcell {idx};fprintf('选择SDK以%s \ n',sdkpath);休息;结尾结尾断言(〜isempty(sdkpath),......Sprintf('%s中没有sdk。请检查系统环境。\ n',sysheaderpath));cccmd = ['xcrun clang -isysroot'deblank(sdkpath)];cppcmd = ['xcrun clang ++  -  isysroot'deblank(sdkpath)];别的CCCMD ='gcc';cppcmd ='g ++';结尾newfilecontent = regexprep(newfilecontent,'Paste_cc',CCCMD);newfilecontent = regexprep(newfilecontent,'paste_cpp',CPPCMD);结尾fid = fopen(mk_name,'w +');FPRINTF(FID,'%s',newfilecontent);fclose(FID);结尾%创建平台构建可执行文件所需的特定命令%运行它。功能[BuildCommand,Runcommand] = CreateBuildandRunCommands(......PackageLocation,UnzipfolderLocation,makefilename,filename)%创建构建和运行命令。如果ISMAC BuildCommand = ['xcrun make -f'makefilename];Runcommand = ['./'文件名'“'文件名'“'];eleesifiSunix BuildCommand = ['make -f'makefilename];Runcommand = ['./'文件名'“'文件名'“'];别的PC上%我们使用生成的BAT文件(应该有2)来帮助%构建生成的代码。这些文件被复制到%UnzipfolderLocation我们可以使用它们来构建。batfilename = [filename'_rtw.bat'];batfilelocation = fullfile(packagepelitocation,'codegen'......filesep,'可执行程序',filesep,filename);Batfiledestination = UnzipfolderLocation;msvc的%,还复制'setup_msvc.bat'FID = FOPEN(FullFile(BatfileLocation,Batfilename));Batfilecontent = Fread(FID,'* char');fclose(FID);如果〜isempty(Regexp(ConvertCharstostrings(Batfilecontent),'setup_msvc.bat''一次'))setup_msvc_batfile = fullfile(batfilelocation,'setup_msvc.bat');COPYFILE(SETUP_MSVC_BATFILE,BATFILEDESTINATION);结尾%将其复制到packngo输出目录。Copyfile(Fullfile(BatfileLocation,Batfilename),BatfilePestination);%我们创建的makefile被命名为“makefile”,而批次%文件是指 _rtw.mk。因此,我们重命名该文件。newmakefilename = [filename'_rtw.mk'];oldmakefilename = makefilename;COPYFILE(Fullfile(Batfiledestination,OldMakeFilename),......Fullfile(BatfileDestination,NewMakeFilename));buildcommand = batfilename;runco​​mmand = [filename'。可执行程序''“'文件名'“'];结尾结尾%使用构建命令构建可执行文件。功能buildexecutable(UnzipfolderLocation,BuildCommand)%call system命令来构建可执行文件。LastDir = CD(UnzipfolderLocation);dircleanup = oncleanup(@()cd(lastdir));[Haderror,Sysresults] =系统(BuildCommand);如果Haderror错误(Sysresults);结尾结尾%获取包含工具箱/ vision子目录的根目录功能matlabdirname = getrootdirname(Unzipfoldername)dirlists = dir(Unzipfoldername);dirlists = dirlists(〜ismember({dirlists.name},{'。''..'}));matlabdirname ='';为了ij = 1:长度(dirlists)thisdirname = dirlists(ij).name;如果(ISFolder(此indirname))%子目录将具有工具箱/愿景[subdir1,hassubdir1] = hassubdirectory(thisdirname,'工具箱');如果hassubdir1 [〜,hassubdir2] = hassubdirectory(subdir1,'想象');如果hassubdir2 matlabdirname = thisdirname;休息;结尾结尾结尾结尾结尾%找到包含指定子目录的目录功能[subdir,hassubdir] = hassubdirectory(dirname,subdirname)dirlists = dir(dirname);dirlists = dirlists(〜ismember({dirlists.name},{'。''..'}));Subdir ='';hassubdir = false;为了ij = 1:长度(dirlists)thisdirname = dirlists(ij).name;thisdir = fullfile(dirname,thisdirname);如果(ISFolder(thisdir)&& strcmp(thisdirname,subdirname))hassubdir = true;subdir = thisdir;休息;结尾结尾结尾
结尾