主要内容

用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 =目录(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创建平台相关的makefile。

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

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

流('->创建“生成命令”和“运行命令”....\n');[buildCommand, runCommand] = createBuildAndRunCommands(zipFileLocation,......UnzipfolderLocation,makefilename,fname);
->创建“生成命令”和“运行命令”....

使用Build命令生成项目。

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

运行Executable和Deploy

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

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函数。main.c.为此示例创建的%与文件的内容兼容% visionFaceTrackingKLTpackNGo_kernel.mmainCFile = fullfile (folderForMainC,'main.c');%处理空间的路径如果包含(mainCFile'') mainCFile = ['“'mainCFile'“'];结束cfg = coder.config ('可执行程序');cfg.postcodegencenmand =“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('*。压缩');断言(Numel(ZipFile)== 1);解压缩(zipfile.name,nuzipfolderlocationname);%unzip内部zip文件在分层packngo中创建。zipFileInternal = dir (fullfile (unzipFolderLocationName'*。压缩'));断言(元素个数(zipFileInternal) = = 3);i = 1:元素个数(zipFileInternal)解压缩(fullfile (unzipFolderLocationName, zipFileInternal (i) . name),......unzipFolderLocationName);结束UnzipfolderLocation = fullfile(zipfilelocation,nuzipfolderlocationname);结束从模板makefile中创建平台相关的makefile。使用%buildinfo获取有关工具链的信息。功能makefilename = createmakefile(VisionDemo_dir,UnzipfolderLocation,Fname)从buildInfo创建Makefile。binfo =负载(fullfile (pwd,'codegen''可执行程序'、帧,'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] = system(['dir / s / b'‘* . cpp‘]);其他的[〜,cfiles] =系统(['找 。/ ''-姓名 ''''*。C''']);[~, cppFiles] = system(['找 。/ ''-姓名 ''''* .cpp'']);结束cIndx = strfind(用,“c”);cppindx = strfind(cppfiles,. cpp的);srcFilesC = [];srcFilesCPP = [];i = 1:长度(cindx)如果i == 1 startIdx = 1;endIdx = cIndx(我);其他的startIdx = cIndx(张)+ 1;endIdx = cIndx(我);结束[~, b, ~] = fileparts(cFiles(startIdx:endIdx));srcFilesC = [srcFilesC''b“c”];%#OK 结束i = 1:长度(cppIndx)如果i == 1 startIdx = 1;endIdx = cppIndx(我);其他的startIdx = cppIndx(张)+ 1;endIdx = cppIndx(我);结束[~, b, ~] = fileparts(cppFiles(startIdx:endIdx));srcFilesCPP = [srcFilesCPP''b. cpp的];%#OK 结束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, defs, srcFiles, matlabDirName});makefileName =“Makefile”;mk_name = fullfile (unzipFolderLocation makefileName);如果isunix如果(ismac) [status, syshederpath] = system('xcode-select-intret-path');断言(状态== 0,[“无法获得进入系统的路径”......'头文件使用'xcode-select -print-path''']);[状态,sdkpath] =系统(['找 'deblank (sysHeaderPath)......“- name“MacOSX * .sdk””]);断言(状态= = 0,'Could not find MacOSX sdk');%可能有多个SDKsdkPathCell = strsplit (sdkPaths,'\ n');idx = 1:元素个数(sdkPathCell)如果~ isempty (sdkPathCell {idx})%选择第一个非空的。sdkPath = sdkPathCell {idx};流('选择SDK以%s \ n', sdkPath);休息结束结束断言(〜isempty(sdkpath),......sprintf ('在%s中没有可用的sdk。请检查系统环境。\n'sysHeaderPath));ccCMD = ['xcrun clang -isysroot'deblank(sdkPath);cppcmd = ['xcrun 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);fclose(FID);结束%创建构建可执行文件所需的平台特定命令%来运行它。功能[buildCommand, runCommand] = createBuildAndRunCommands(......PackageLocation,UnzipfolderLocation,MakeFilename,Filename)%创建生成并运行命令。如果ismac buildCommand = ['xcrun make -f'makefileName];runCommand = [“。/”文档名称“””文档名称'“'];elsef.iSunix BuildCommand = ['make -f'makefileName];runCommand = [“。/”文档名称“””文档名称'“'];其他的PC百分比我们使用生成的BAT文件(应该有2)来帮助%生成生成的代码。这些文件被复制到% unzipFolderLocation,我们可以使用它们来构建。batFilename =[文件名“_rtw.bat”];batfilelocation = fullfile(packagepelitocation,'codegen'......filesep,'可执行程序'filesep,文件名);batFileDestination = unzipFolderLocation;% For MSVC,也复制'setup_msvc.bat'FID = FOPEN(Fullfile(BatfileLocation,Batfilename));Batfilecontent = fread(fid,“*字符”);fclose(FID);如果~ isempty(正则表达式(convertCharsToStrings (batFileContent),'setup_msvc.bat'“一次”) setup_msvc_batFile = fullfile(batFilelocation,'setup_msvc.bat');COPYFILE(SETUP_MSVC_BATFILE,BATFILEDESTINATION);结束%复制到packNGo输出目录。COPYFILE(FullFile(BatfileLocation,Batfilename),Batfiledestination);我们创建的Makefile命名为“Makefile”,而批处理文件命名为“Makefile”% file指的是_rtw.mk。因此,我们重命名该文件。newmakefilename = [filename“_rtw.mk”];oldMakefilename = makefileName;拷贝文件(fullfile (batFileDestination oldMakefilename),......Fullfile(Batfiledestination,NewMakeFilename));BuildCommand = Batfilename;runco​​mmand = [filename. exe”“””文档名称'“'];结束结束%使用Build命令生成可执行文件。功能buildexecutable(UnzipfolderLocation,BuildCommand)%调用系统命令来构建可执行文件。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: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},{“。”“. .”}));Subdir ='';hasSubDir = false;ij=1:length(dirLists) thisDirName = dirLists(ij).name;thisDirName thisDir = fullfile(目录名);如果(isfolder(thisDir) && strcmp(thisDirName, subDirName)) hasSubDir = true;子目录= thisDir;休息结束结束结束
结束