主要内容

代码生成与PackNGo脸跟踪

这个例子展示了如何生成代码使用KLT人脸检测和跟踪算法packNGo函数示例。的packNGo(MATLAB编码器)函数在一个压缩包所有相关文件的zip文件你可以搬迁,解压缩,并重建你的项目没有MATLAB在另一个开发环境。这个示例还展示了如何创建一个makefile packNGo内容,重建源文件最后MATLAB环境外运行独立的可执行文件。

这个例子需要MATLAB®编码器™许可证。

这个例子是一个函数与顶部的主体和辅助例程的形式嵌套函数在下面。

函数FaceTrackingKLTpackNGoExample ()

设置你的c++编译器

要运行这个示例,您必须访问一个c++编译器,您必须配置使用的墨西哥人设置c++的命令。有关更多信息,请参见选择一个c++编译器。如果你MATLAB主机上部署应用程序,使用兼容的c++编译器编译器用于构建OpenCV库。有关更多信息,请参见可移植的C代码生成使用OpenCV库的功能

打破算法的计算部分到一个单独的MATLAB函数

MATLAB编码器需要MATLAB代码是一个函数的形式,以生成C代码。这个例子的主要算法的代码驻留在一个函数调用FaceTrackingKLTpackNGo_kernel.m。这个文件来自使用KLT人脸检测和跟踪算法。学习如何修改MATLAB代码兼容的代码生成,你可以看看介绍代码生成功能匹配和登记

文件名=“FaceTrackingKLTpackNGo_kernel.m”;visiondemo_dir = pwd;currentDir = pwd;%保存当前目录文件名= fullfile (visiondemo_dir,文件名);

配置代码生成理由packNGo

创建一个代码生成配置对象与packNGo EXE输出函数调用post代码生成阶段。

codegenArgs = createCodegenArgs (visiondemo_dir);

设置代码生成环境

改变输出目录的名字。

codegenOutDir = fullfile (visiondemo_dir,“codegen”);mkdir (codegenOutDir);

路径添加到现有的目录来获得必要的文件。

currentPath =目录(visiondemo_dir);pathCleanup = onCleanup(@()路径(currentPath));cd (codegenOutDir);dirChange = onCleanup (@ () cd (currentDir));

创建压缩文件打包

调用codegen packNGo函数调用的命令。

流(”- >“生成代码(可能需要几分钟).... \ n”);codegen (codegenArgs{:},文件名);
- >生成代码(可能需要几分钟)....代码生成成功。

注意,而不是使用codegen命令,您可以打开一个对话框和启动代码生成项目使用codegen(MATLAB编码器)。使用post代码生成命令packNGo函数来创建一个zip文件。

建立独立的可执行文件

将zip文件解压缩到一个新文件夹。注意,zip文件包含源文件,头文件,库,MAT-file包含构建信息对象,数据文件。unzipPackageContents和其他辅助功能都包含在附录。

zipFileLocation = codegenOutDir;流(“- >压缩文件.... \ n”);unzipFolderLocation = unzipPackageContents (zipFileLocation);
- >压缩文件....

从一个模板创建依赖于平台makefile makefile。

流(“- >创建makefile .... \ n”);(帧,~ ~)= fileparts(文件名);makefileName = createMakeFile (visiondemo_dir, unzipFolderLocation、帧);
- >创建makefile ....

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

流(“- >创建“构建命令”和“命令”.... \ n”);[buildCommand, runCommand] = createBuildAndRunCommands (zipFileLocation,unzipFolderLocation, makefileName、帧);
- >创建“构建命令”和“运行命令”....

使用构建命令构建项目。

流(“- >构建可执行.... \ n”);buildExecutable (unzipFolderLocation buildCommand);
- >构建可执行....

运行可执行文件和部署

运行可执行程序,并验证它的工作原理。

cd (unzipFolderLocation);系统(runCommand);

应用程序可以被部署在另一台机器通过复制的可执行文件和库文件。

isPublishing = ~ isempty (snapnow (“得到”));如果~ isPublishing%跳过打印目录的html页面流(的可执行文件和库文件位于以下文件夹:\ n % s \ n”,unzipFolderLocation);流(”重新执行运行以下命令:\ n”);流(“1。cd (“% s”) \ n ',unzipFolderLocation);流(“2。系统(“% s”) \ n”runCommand);结束

附录-辅助函数

%配置编码器来创建可执行的。使用packNGo邮政编码%生成阶段。函数codegenArgs = createCodegenArgs (folderForMainC)%创建代码生成所需参数。%为独立的可执行的一个主要的C函数是必需的。c的%为这个例子创建兼容的文件的内容% visionFaceTrackingKLTpackNGo_kernel.mmainCFile = fullfile (folderForMainC,“c”);%处理与空间路径如果包含(mainCFile' ')mainCFile = (“””mainCFile“””];结束cfg = coder.config (exe”);cfg。PostCodeGenCommand =“packNGo (buildInfo,“packType”,“分层”);“;cfg。CustomSource = mainCFile;cfg。CustomInclude = folderForMainC;cfg。EnableOpenMP = false;codegenArgs = {“配置”cfg};结束%创建一个文件夹并解压缩packNGo内容。函数unzipFolderLocation = unzipPackageContents (zipFileLocation)% zip文件解压缩打包。unzipFolderLocationName =“unzipPackNGo”;mkdir (unzipFolderLocationName);%得到packNGo生成的zip文件的名称。zipFile = dir (‘* . zip”);断言(元素个数(zipFile) = = 1);解压缩(zipFile.name unzipFolderLocationName);%解压缩内部分层packNGo中创建zip文件。zipFileInternal = dir (fullfile (unzipFolderLocationName‘* . zip”));断言(元素个数(zipFileInternal) = = 3);i = 1:元素个数(zipFileInternal)解压缩(fullfile (unzipFolderLocationName, zipFileInternal (i) . name),unzipFolderLocationName);结束unzipFolderLocation = fullfile (zipFileLocation unzipFolderLocationName);结束%从模板创建依赖于平台makefile makefile。使用% buildInfo信息工具链。函数makefileName = createMakeFile (visiondemo_dir unzipFolderLocation、帧)%从buildInfo创建Makefile。binfo =负载(fullfile (pwd,“codegen”,exe”、帧,“buildInfo.mat”));lastDir = cd (unzipFolderLocation);dirCleanup = onCleanup (@ () cd (lastDir));%得到包含工具箱的根目录/子目录matlabDirName = getRootDirName (unzipFolderLocation);%得到定义horzcat_with_space = @ (cellval) sprintf (' % s ',cellval {:});def = horzcat_with_space (getDefines (binfo.buildInfo));%得到源文件列表如果ispc[~,用]=系统([“dir / s / b”‘* . c”]);[~,cppFiles] =系统([“dir / s / b”‘* . cpp‘]);其他的[~,用]=系统([“。/”“- name”“* . c”]);[~,cppFiles] =系统([“。/”“- name”“* . cpp”]);结束cIndx = strfind(用,“c”);cppIndx = strfind (cppFiles,. cpp的);srcFilesC = [];srcFilesCPP = [];i = 1:长度(cIndx)如果我= = 1 startIdx = 1;endIdx = cIndx(我);其他的startIdx = cIndx(张)+ 1;endIdx = cIndx(我);结束(~ b ~) = fileparts(用(startIdx: endIdx));srcFilesC = [srcFilesC' 'b“c”];% #好< AGROW >结束i = 1:长度(cppIndx)如果我= = 1 startIdx = 1;endIdx = cppIndx(我);其他的startIdx = cppIndx(张)+ 1;endIdx = cppIndx(我);结束(~ b ~) = fileparts (cppFiles (startIdx: endIdx));srcFilesCPP = [srcFilesCPP' 'b. cpp的];% #好< AGROW >结束srcFiles = [srcFilesC' 'srcFilesCPP];%得到依赖于平台的名字如果isunix% mac和linuxtmf =“TemplateMakefilePackNGo_unix”;如果ismac archDir =“maci64”;dllExt =“dylib”;其他的archDir =“glnxa64”;dllExt =“所以”;结束其他的tmf =“TemplateMakefilePackNGo_win”;archDir =“win64”;dllExt =“dll”;结束%现在,我们已经定义了,允许创建一个依赖于平台makefile%的模板。fid = fopen (fullfile (visiondemo_dir tmf));filecontent = char(从文件中读(fid) ');文件关闭(fid);newfilecontent = regexprep (filecontent,{“PASTE_ARCH”,“PASTE_EXT”,“PASTE_DEFINES”,“PASTE_SRCFILES”,“PASTE_MATLAB”},{archDir, dllExt, def、srcFiles matlabDirName});makefileName =“Makefile”;mk_name = fullfile (unzipFolderLocation makefileName);如果isunix如果(ismac)[地位,sysHeaderPath] =系统(“xcode-select -print-path”);断言(状态= = 0,(“无法获取路径系统”的头文件使用“xcode-select -print-path”]);(地位、sdkPaths) =系统(“xcrun sdk macosx——show-sdk-path”);断言(状态= = 0,“找不到MacOSX sdk”);%可能有多个SDKsdkPathCell = strsplit (sdkPaths,' \ n ');idx = 1:元素个数(sdkPathCell)如果~ isempty (sdkPathCell {idx})%选择第一个不是空的。sdkPath = sdkPathCell {idx};流(“选择SDK在% s \ n”,sdkPath);打破;结束结束断言(~ isempty (sdkPath),sprintf (没有sdk % s。请检查系统环境。\ n”sysHeaderPath));ccCMD = [“xcrun奏鸣曲-isysroot”deblank (sdkPath)];cppCMD = [“xcrun叮当声+ + -isysroot 'deblank (sdkPath)];其他的ccCMD =“海合会”;cppCMD =“g++”;结束newfilecontent = regexprep (newfilecontent,“PASTE_CC”,ccCMD);newfilecontent = regexprep (newfilecontent,“PASTE_CPP”,cppCMD);结束fid = fopen (mk_name,“w +”);流(fid检测器,' % s ',newfilecontent);文件关闭(fid);结束%创建特定于平台的命令需要构建可执行%来运行它。函数[buildCommand, runCommand] = createBuildAndRunCommands (packageLocation、unzipFolderLocation makefileName文件名)%创建构建和运行命令。如果ismac buildCommand = [“xcrun使- f”makefileName];runCommand = [“。/”文件名“””文件名“””];elseifisunix buildCommand = [“让- f”makefileName];runCommand = [“。/”文件名“””文件名“””];其他的我们使用电脑生成的蝙蝠文件%(应该有2)的帮助%建立生成的代码。这些文件复制到% unzipFolderLocation,我们可以使用它们来构建。batFilename =[文件名“_rtw.bat”];batFilelocation = fullfile (packageLocation,“codegen”,filesep,exe”filesep,文件名);batFileDestination = unzipFolderLocation;还MSVC的%,复制“setup_msvc.bat”fid = fopen (fullfile (batFilelocation batFilename));batFileContent =从文件中读(fid,“*字符”);文件关闭(fid);如果~ isempty(正则表达式(convertCharsToStrings (batFileContent),“setup_msvc.bat”,“一次”))setup_msvc_batFile = fullfile (batFilelocation“setup_msvc.bat”);拷贝文件(setup_msvc_batFile batFileDestination);结束%将其复制到packNGo输出目录。拷贝文件(fullfile (batFilelocation batFilename) batFileDestination);% Makefile我们创建了名为“Makefile”,而批处理文件是指<文件名> _rtw.mk %。因此我们重命名文件。newMakefileName =[文件名“_rtw.mk”];oldMakefilename = makefileName;拷贝文件(fullfile (batFileDestination oldMakefilename),fullfile (batFileDestination newMakefileName));buildCommand = batFilename;runCommand =[文件名. exe”“””文件名“””];结束结束%与构建建立可执行命令。函数buildExecutable (unzipFolderLocation buildCommand)%调用系统命令来构建可执行。lastDir = cd (unzipFolderLocation);dirCleanup = onCleanup (@ () cd (lastDir));[hadError, sysResults] =系统(buildCommand);如果hadError错误(sysResults);结束结束%得到包含工具箱的根目录/子目录函数matlabDirName = getRootDirName (unzipFolderName)目录= dir (unzipFolderName);目录=目录(~ ismember ({dirLists.name}, {“。”,“. .”}));matlabDirName =;ij = 1:长度(目录)thisDirName =目录(ij) . name;如果(isfolder (thisDirName))%子目录将工具箱/愿景[subDir1, hasSubDir1] = hasSubdirectory (thisDirName,“工具箱”);如果hasSubDir1 [~, hasSubDir2] = hasSubdirectory (subDir1,“愿景”);如果hasSubDir2 matlabDirName = thisDirName;打破;结束结束结束结束结束%找到包含指定的子目录的目录函数[子目录,hasSubDir] = hasSubdirectory(目录名,subDirName)目录= dir(目录名);目录=目录(~ ismember ({dirLists.name}, {“。”,“. .”}));子目录=;hasSubDir = false;ij = 1:长度(目录)thisDirName =目录(ij) . name;thisDirName thisDir = fullfile(目录名);如果(isfolder (thisDir) & & strcmp (thisDirName subDirName)) hasSubDir = true;子目录= thisDir;打破;结束结束结束
结束