主要内容

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 Coder要求MATLAB代码以函数的形式生成C代码。本例的主算法代码驻留在一个名为FaceTrackingKLTpackNGo_kernel.m.该文件派生自基于KLT算法的人脸检测与跟踪.要学习如何修改MATLAB代码以使其与代码生成兼容,可以查看示例介绍带有特征匹配和注册的代码生成

文件名=“FaceTrackingKLTpackNGo_kernel.m”;Visiondemo_dir = pwd;currentDir = pwd;%存储当前目录文件名= 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命令。

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

注意,不使用codegen命令,您可以打开一个对话框并使用codegen(MATLAB编码器).使用邮政编码生成命令和packNGo函数创建zip文件。

构建独立可执行文件

将zip文件解压缩到一个新文件夹中。注意,zip文件包含源文件、头文件、库、包含构建信息对象的mat文件、数据文件。unzipPackageContents和其他辅助函数包含在附录中。

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

从模板生成文件创建平台相关的生成文件。

流(->创建makefile ....\n');[~, fname, ~] = fileparts(fileName);makefileName = createMakeFile(visiondemo_dir, unzipFolderLocation, fname);
->正在创建makefile ....

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

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

使用Build命令构建项目。

流('->构建可执行文件....\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 = code .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);结束从模板生成文件创建平台相关的生成文件。使用获取有关工具链的信息。函数makefileName = createMakeFile(visiondemo_dir, unzipFolderLocation, fname)从buildInfo创建Makefile。Binfo = load(fullfile(pwd),“codegen”exe”、帧,“buildInfo.mat”));lastDir = cd(unzipFolderLocation);dirCleanup = onCleanup(@()cd(lastDir));获取包含工具箱/视觉子目录的根目录matlabDirName = getRootDirName(unzipFolderLocation);% Get定义Horzcat_with_space = @(cellval)sprintf(' % s ', cellval {:});defs = horzcat_with_space(getdefinitions (binfo.buildInfo));获取源文件列表如果ispc [~, cFiles] = system(['dir /s/b '‘* . c”]);[~, cppFiles] = system(['dir /s/b '‘* . cpp‘]);其他的[~, cFiles] = system(['find ./ '“- name”“* . c”]);[~, cppFiles] = system(['find ./ '“- name”“* . 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 . srcFilesC' 'b“c”];% #好< AGROW >结束i = 1:长度(cppIndx)如果i = 1 startIdx = 1;enddix = cppIndx(i);其他的startdx = cppIndx(i-1)+1;enddix = cppIndx(i);结束[~, b, ~] = fileparts(cppFiles(startIdx:endIdx));srcFilesCPP = [srcFilesCPP . srcFilesCPP' 'b. cpp的];% #好< AGROW >结束srcFiles = [srcFilesC . srcFiles' 'srcFilesCPP];获取平台相关的名称如果isunixMAC和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(fread(fid)');文件关闭(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) [status,sysHeaderPath] = system(“xcode-select -print-path”);断言(状态= = 0,(“无法获取到系统的路径”...'头文件使用'xcode-select -print-path'']);[status,sdkPaths] = system([“发现”deblank(sysHeaderPath)...' name " MacOSX*.sdk "]);断言(状态= = 0,“无法找到MacOSX sdk”);可能有多个SDKsdkPathCell = strsplit(sdkPaths,' \ n ');idx = 1:numel(sdkPathCell)如果~ isempty (sdkPathCell {idx})选择第一个不为空的。sdkPath = sdkPathCell{idx};流('在%s\n中选择SDK ', sdkPath);打破结束结束断言(~ isempty (sdkPath),...sprintf (' %s中没有可用的sdk。请检查系统环境。\n'sysHeaderPath));ccCMD = [' cxrun clang -isysroot 'deblank(sdkPath)];cppCMD = [“xcrrun clang++ -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 = [' xcrrun make -f 'makefileName];runCommand = [“。/”文件名“””文件名“””];elseifisunix buildCommand = [' make -f 'makefileName];runCommand = [“。/”文件名“””文件名“””];其他的%在PC上我们使用生成的BAT文件(应该有2个)来帮助%构建生成的代码。这些文件被复制到% unzipFolderLocation,在那里我们可以使用它们来构建。batFilename = [fileName .“_rtw.bat”];batFilelocation = fullfile(packageLocation,“codegen”...filesep,exe”filesep,文件名);batFileDestination = unzipFolderLocation;%对于MSVC,也复制'setup_msvc.bat'fid = fopen(fullfile(batFilelocation, batFilename));batFileContent = fread(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”,而批处理% file指_rtw.mk。因此我们重命名该文件。newMakefileName = [fileName .“_rtw.mk”];oldMakefilename = makefileName;拷贝文件(fullfile (batFileDestination oldMakefilename),...fullfile (batFileDestination newMakefileName));buildCommand = batFilename;runCommand = [fileName .. exe”“””文件名“””];结束结束使用构建命令构建可执行文件。函数buildExecutable (unzipFolderLocation buildCommand)调用系统命令构建可执行文件。lastDir = cd(unzipFolderLocation);dirCleanup = onCleanup(@()cd(lastDir));[hadError, sysResults] = system(buildCommand);如果hadError错误;结束结束获取包含工具箱/视觉子目录的根目录函数matlabDirName = getRootDirName(unzipFolderName) dirLists = dir(unzipFolderName);dirLists = dirLists(~ismember({dirLists.name},{“。”“. .”}));matlabDirName =ij=1:length(dirLists) thisDirName = dirLists(ij).name;如果(isfolder (thisDirName))%子目录将有工具箱/视野[subDir1, hasSubDir1] = hasSubdirectory(thisDirName,“工具箱”);如果hasSubDir1 [~, hasSubDir2] = hasSubdirectory(subDir1,“愿景”);如果hasSubDir2 matlabDirName = thisDirName;打破结束结束结束结束结束查找包含指定子目录的目录函数[subDir, hasSubDir] = hasSubdirectory(dirName, subDirName) dirLists = dir(dirName);dirLists = dirLists(~ismember({dirLists.name},{“。”“. .”}));子目录=;hasSubDir = false;ij=1:length(dirLists) thisDirName = dirLists(ij).name;fullfile(dirName,thisDirName);如果(isfolder(thisDir) && strcmp(thisDirName, subDirName)) hasSubDir = true;subDir = thisDir;打破结束结束结束
结束