主要内容

代码生成与PackNGo的面部跟踪

此示例显示如何从生成代码基于KLT算法的人脸检测与跟踪示例与packNGo函数。的帕克恩戈(MATLAB编码器)函数将所有相关文件打包到一个压缩zip文件中,这样您就可以在没有MATLAB的情况下在另一个开发环境中重新部署、解包和重建项目。这个示例还展示了如何为packNGo内容创建一个makefile,重新构建源文件,并最终在MATLAB环境外运行独立的可执行文件。

这个例子需要MATLAB®Coder™许可证。

此示例是一个函数,其主体位于顶部,辅助程序例程的形式为嵌套的函数在下面

函数FaceTrackingKLTpackNGoExample ()

设置C++编译器

要运行这个示例,必须访问C++编译器,并且必须使用“MEX -设置C++”命令配置它。选择一个c++编译器如果在Matlab主机上部署应用程序,使用与编译OpenCV库的编译器兼容的C++编译器。为使用OpenCV库的函数生成可移植C代码.

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

MATLAB Coder要求MATLAB代码以函数的形式生成C代码。这个示例的主要算法代码驻留在一个被调用的函数中FaceTrackingKLTpackNGo_kernel.m。此文件源于基于KLT算法的人脸检测与跟踪。要了解如何修改MATLAB代码以使其与代码生成兼容,您可以查看示例基于特征匹配和配准的代码生成简介.

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

为。配置代码生成参数帕克恩戈

在代码生成后阶段,使用packNGo函数调用为EXE输出创建代码生成配置对象。

codegenArgs=createCodegenArgs(visiondemo_-dir);

设置代码生成环境

更改输出目录名称。

codegenOutDir=完整文件(visiondemo_-dir,“codegen”);mkdir (codegenOutDir);

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

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

创建打包的Zip文件

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

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

请注意,您可以使用以下命令打开对话框并启动代码生成项目,而不是使用codegen命令codegen(MATLAB编码器)。使用带有packNGo函数的邮政编码生成命令创建zip文件。

构建独立的可执行文件

将zip文件解压缩到新文件夹中。请注意,zip文件包含源文件、头文件、库、包含生成信息对象的MAT文件、数据文件。解压缩包内容附录中包括了其他辅助功能。

zipFileLocation=codegenOutDir;fprintf(“->解压文件….\n”);unzipFolderLocation = unzipPackageContents (zipFileLocation);
->解压文件。。。。

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

fprintf(“->正在创建makefile….\n”);[~,fname,~]=fileparts(文件名);makefileName=createMakeFile(visiondemo_dir,unzipFolderLocation,fname);
->正在创建makefile。。。。

创建生成项目和运行项目所需的命令。

fprintf('->正在创建“生成命令”和“运行命令”…\n);[buildCommand,runCommand]=createBuildAndRunCommands(zipFileLocation,...unzipFolderLocation, makefileName、帧);
->正在创建“构建命令”和“运行命令”。。。。

使用Build命令生成项目。

fprintf(“- >构建可执行…\ n”);buildExecutable(unzipFolderLocation,buildCommand);
->正在生成可执行文件。。。。

运行可执行文件并部署

运行可执行文件并验证它是否工作。

cd(unzipFolderLocation);系统(runCommand);

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

isPublishing=~isempty(snapnow)(“得到”));如果~i发布%跳过将目录打印到html页面fprintf('可执行文件和库文件位于以下文件夹:\n%s\n',unzipFolderLocation);fprintf('要重新执行,请运行以下命令:\n');fprintf(“1。cd(“% s”)\ n ',unzipFolderLocation);fprintf(“2.系统(“%s”)\n”,runCommand);终止

附录-辅助功能

%配置编码器以创建可执行文件。在post代码处使用packNGo%世代阶段。函数codegenArgs=createCodegenArgs(folderForMainC)%创建代码生成所需的参数。%对于独立的可执行文件,需要一个主C函数。c的为本例创建的%与文件内容兼容%VisionFaceTrackingKltpackingo_kernel.mmainCFile=fullfile(文件夹格式),“c”);%用空格处理路径如果包含(mainCFile,' ')mainCFile=[“””维护文件“””];终止cfg=coder.config(exe”);cfg。PostCodeGenCommand =“packNGo(buildInfo”,“packType”,“hierarchical”);”;cfg.CustomSource=mainCFile;cfg.CustomInclude=folderForMainC;cfg.EnableOpenMP=false;codegenArgs={“-config”cfg};终止%创建一个文件夹并将packNGo内容解压缩到其中。函数解压文件夹位置=解压包内容(zipFileLocation)%解压缩打包的zip文件。unzipFolderLocationName=“unzipPackNGo”;mkdir(unzipFolderLocationName);%获取packNGo生成的zip文件的名称。zipFile = dir (‘* . zip”);断言(元素个数(zipFile) = = 1);解压缩(zipFile.name unzipFolderLocationName);解压分层packNGo中创建的内部zip文件。zipFileInternal=dir(fullfile(unzipFolderLocationName,‘* . zip”));断言(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=加载(完整文件(pwd),“codegen”,exe”,fname,“buildInfo.mat”));lastDir = cd (unzipFolderLocation);dirCleanup = onCleanup (@ () cd (lastDir));%获取包含toolbox/vision子目录的根目录matlabDirName=getRootDirName(unzipFolderLocation);%得到定义horzcat_与_空格=@(cellval)sprintf(“%s”, cellval {:});def = horzcat_with_space (getDefines (binfo.buildInfo));%获取源文件列表如果ispc [~, cFiles] = system([“dir / s / b”“*.c”]);[~,cppFiles]=系统([“dir / s / b”“*.cpp”]);其他的[~, cFiles] = system([“。/”“- name”“* . c”]);[~,cppFiles]=系统([“。/”“- name”“* . cpp”]);终止cIndx=strfind(c文件,“.c”);cppIndx = strfind (cppFiles,“.cpp”);srcFilesC=[];srcFilesCPP=[];对于i = 1:长度(cIndx)如果i == 1 startIdx = 1;endIdx = cIndx(我);其他的startIdx=cIndx(i-1)+1;endIdx=cIndx(i);终止[~,b,~]=fileparts(cFiles(startIdx:endIdx));srcFilesC=[srcFilesC' 'B“.c”];% #好< AGROW >终止对于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”];% #好< AGROW >终止srcFiles = [srcFilesC' 'srcFilesCPP];%获取与平台相关的名称如果isunix%mac和linux都有tmf=“TemplateMakefilePackNGo_unix”如果ismac archDir =“maci64”;dllExt=“动态库”其他的阿奇迪尔=“glnxa64”;dllExt=“那么”终止其他的tmf=“TemplateMakefilePackNGo_-win”;阿奇迪尔=“win64”;dllExt=“dll”终止%现在我们已经定义了,让我们创建一个依赖于平台的makefile%从模板。fid=fopen(fullfile(visiondemo_dir,tmf));filecontent=char(fread(fid)”;fclose(fid);newfilecontent=regexprep(filecontent,...{“粘贴拱门”,“粘贴EXT”,“粘贴定义”,“粘贴文件”,“粘贴MATLAB”},...{archDir,dllExt,defs,srcFiles,matlabDirName});makefileName=“Makefile”;mk_name=fullfile(unzipFolderLocation,makefileName);如果isunix如果(ismac)[状态,sysHeaderPath]=系统(“xcode-select -print-path”);断言(状态= = 0,('无法获取系统的路径'...'使用“xcode-select-打印路径”的头文件''']);[status,sdkPaths] = system([“发现”deblank(系统头路径)...'-名称''MacOSX*.sdk'']);断言(状态==0,'找不到MacOSX sdk');%可能有多个SDKsdkPathCell=strsplit(sdkPaths,' \ n ');对于idx=1:numel(sdkPathCell)如果~isempty(sdkPathCell{idx})%选择第一个不是空的。sdkPath=sdkPathCell{idx};fprintf(在%s\n中选择SDK,sdkPath);打破终止终止断言(~ isempty (sdkPath),...斯普林特('在%s中没有可用的sdk。请检查系统环境。\n',sysHeaderPath));ccCMD=['xcrun clang -isysroot 'deblank(sdkPath);cppCMD = ['xcrun clang++ -isysroot 'deblank(sdkPath);其他的ccCMD=“gcc”; cppCMD=“g++”终止newfilecontent = regexprep (newfilecontent,“粘贴抄送”,ccCMD);newfilecontent=regexprep(newfilecontent,“粘贴CPP”,cppCMD);终止fid = fopen (mk_name,“w +”);fprintf(fid,“%s”, newfilecontent);文件关闭(fid);终止%创建构建可执行文件和%运行它。函数[buildCommand,runCommand]=createBuildAndRunCommands(...packageLocation、unzipFolderLocation makefileName文件名)%创建build和run命令。如果ismac buildCommand=[' xcron make -f 'makefileName];runCommand=['./'文件名' "'文件名“””];elseifisunix buildCommand = [' make -f 'makefileName];runCommand=['./'文件名' "'文件名“””];其他的%在PC上,我们使用生成的BAT文件(应该有2个)来帮助%生成生成的代码。这些文件将复制到%取消ZipFolderLocation,在那里我们可以使用它们进行构建。batFilename=[fileName]"蝙蝠"];batFilelocation = fullfile (packageLocation,“codegen”,...文件集,exe”,filesep,fileName);batFileDestination=unzipFolderLocation;%对于MSVC,还要复制“setup\u MSVC.bat”fid = fopen(fullfile(batFilelocation, batFilename));batFileContent =从文件中读(fid,“*char”);文件关闭(fid);如果~isempty(regexp(convertCharsToString(batFileContent)),“setup_msvc.bat”,“一次”))setup\u msvc\u batFile=fullfile(batFilelocation,“setup_msvc.bat”);拷贝文件(setup_msvc_batFile batFileDestination);终止%将其复制到packNGo输出目录。拷贝文件(fullfile (batFilelocation batFilename) batFileDestination);%我们创建的Makefile名为“Makefile”,而批处理%文件引用了\u rtw.mk。因此我们重命名了该文件。newMakefileName =[文件名"rtw.mk"];oldMakefilename=makefileName;copyfile(fullfile(batFileDestination,oldMakefilename),...fullfile (batFileDestination newMakefileName));buildCommand = batFilename;runCommand =[文件名“.exe”' "'文件名“””];终止终止%使用Build命令生成可执行文件。函数buildExecutable (unzipFolderLocation buildCommand)%调用系统命令以生成可执行文件。lastDir = cd (unzipFolderLocation);dirCleanup = onCleanup (@ () cd (lastDir));[hadError, sysResults] = system(buildCommand);如果hadError错误(sysResults);终止终止%获取包含toolbox/vision子目录的根目录函数matlabDirName=getRootDirName(unzipFolderName)dirLists=dir(unzipFolderName);dirLists=dirLists(~ismember({dirLists.name}){'.','..'}));matlabDirName =''对于ij=1:length(dirLists) thisDirName = dirLists(ij).name;如果(isfolder(thisDirName))%子目录将具有toolbox/vision[subDir1,hasSubDir1]=hasSubdirectory(thisdirename,“工具箱”);如果hasSubDir1[~,hasSubDir2]=hasSubdirectory(subDir1,“愿景”);如果hasSubDir2 matlabDirName = thisDirName;打破终止终止终止终止终止%查找包含指定子目录的目录函数[subDir, hasSubDir] = hasSubdirectory(dirName, subDirName) dirLists = dir(dirName);目录=目录(~ ismember ({dirLists.name}, {'.','..'}));子目录='';hasSubDir=假;对于ij=1:length(dirLists)thisDirName=dirLists(ij).name;thisDir=fullfile(dirName,thisDirName);如果(isfolder(thisDir)和strcmp(thisDirName,subDirName))hasSubDir=true;subDir=thisDir;打破终止终止终止
终止