Simulin金宝appk上的Guy

金宝appSimulink &基于模型的设计

链接到一个动态库从MATLAB编码器的Windows计算机视觉应用程序

在一个以前的文章,我演示了从MATLAB函数生成C/ c++代码的基础知识,以及如何使用该代码创建可用于外部应用程序的动态库(DLL)。今天,我想在这篇文章的基础上,把它应用到一个更复杂的例子中。假设我们已经在MATLAB®中开发了一些代码,使用计算机视觉工具箱执行一些图像分析,并希望在外部c++应用程序中利用这种能力。在本文档中,我们将通过从一些MATLAB例程创建一个DLL并从外部c++代码调用它们来演示这个工作流。

MATLAB图像处理代码

在这个例子中,我们的代码在电路板上执行特征检测,以找到外部应用程序将用于某些进程的兴趣点(角落)。在MATLAB中,我们需要加载图像,检测一些特征并提取它们。提取的特征将在我们的应用程序中使用,因此我们需要访问表示特征位置的结果数组点。
执行此操作的原始MATLAB代码是:
%客户端的映像文件名,这将是一个参数
imFile =“circuit.jpg”
%质量因子——在客户端,这将是一个参数
qFac = 0.1;
读取灰度图像
I = imread(imFile);
在图像中找到角落候选人
角= detectHarrisFeatures(I,“MinQuality”, qFac);
提取有效的内核
[~,valid_corners] = extractFeatures(I,corners);
为了在MATLAB端验证结果,我们将在图像上叠加提取的有效角。(我们的客户端代码将把这些角用于其他目的。)
J = insertMarker(I, valid_corners,“+”);
图(100);
clf
imshow (J);
为了使我们的MATLAB代码适合于生成和生产,我们将上面的代码放入一个函数中。这个函数将有参数检查以及一个将角点和有效性标志传递回客户端例程的接口。下面是适合代码生成的例程:
函数[X, valid] = cornerFinder(imFileName, qFac)
在输入文件上使用给定质量因子的哈里斯角检测器
% by qFac。
The MathWorks(R), Inc.版权所有
执行基本参数类型检查
参数(输入)
imFileName(: 1)字符
qFac
结束
为输出分配类型(单个,uint32, boolean)
X = 0 (0, 2,“喜欢”, qFac);
Valid = false;
确保质量系数在范围内。
如果qFac < 0 || qFac > 1
流(“错误:质量因子必须在0到1之间。\n”);
返回
结束
测试给定文件是否存在且可读
fID = fopen(imFileName,“r”);
如果fID == -1
流("错误:未找到文件%s。\n", imFileName);
返回
结束
%关闭文件测试
文件关闭(fID);
从磁盘获取映像
I = imread(imFileName);
计算并提取角点特征
角= detectHarrisFeatures(I,“MinQuality”, qFac);
[~,valid_corners] = extractFeatures(I,corners);
在客户端和的输出数组中存储角位置
%记录点数。将有效标志设置为true。
X = valid_corners.Location;
Valid = true;
结束

生成代码并为函数创建动态库

为了为函数生成代码并将其编译为Windows环境的DLL,我们创建了一个coder.config对象。计算机视觉调用要求代码在RowMajor我们在代码配置中设置了模式。然后我们为两个输入定义虚拟参数:
  • qFac:一个单一的精度质量因素
  • imFile:文件名的可变大小字符数组(这里我们使用coder.typeof要指定这一点)
方法生成代码codegen命令。这将创建MATLAB例程的C代码表示,我们稍后将其编译成动态库。
CFG = code .config(“dll”);
cfg。RowMajor = true;
cfg.GenCodeOnly = true;
为编码器定义输入参数类型
qFac = single(0.1);
imFile = code .typeof(“一个”, [1,2048], [0,1]);
调用编码器生成动态库
codegen-config cfg拐角查找器。m -args {imFile, qFac} -nargout 2 -report
代码生成成功:查看报告
从报告中查看cornerFinder.h可以看到生成的库的客户端接口。它有原型的角查找器C函数。注意,该函数有三个输入参数,图像文件的名称,它的尺寸和质量因子。有两个输出,点数组和有效标志。接口代码的重要部分在这里:
(const char imFileName_data[],
const int imFileName_size[2], float qFac
emxArray_real32_T *X, boolean_T *valid);
稍后我们将使用这些信息来构造客户端代码。

打包库及其依赖项

现在我们已经生成了库代码,我们需要做两件事。首先,我们需要提供如何在客户端构建库的说明。要做到这一点,我们将使用codebuild生成CMake工件的功能。其次,我们将收集代码和所有依赖库,并将它们打包以便分发。我们将使用packNGo来自MATLAB的函数。这将生成一个zip文件,其中包含我们在客户端需要的所有内容。
codebuild (”。/ codegen / dll / cornerFinder”“BuildMethod”“CMake”“BuildVariant”“SHARED_LIBRARY”);
packNGo (”。/ codegen / dll / cornerFinder”“packType”“分层”“文件名”“myCornerFinderExample”);
这个命令序列生成了我们需要传递给客户端的内容。codebuild命令创建一个CMakeLists.txt文件,我们最终将使用该文件从我们的代码创建一个DLL。packNGo命令生成一个名为myCornerFinderExample.zip的文件。在这个文件中还有另外两个zip文件,mlrFiles.zip和sDirFiles.zip。第一个包含计算机视觉功能所需的所有MATLAB运行时文件和库,第二个包含生成的代码。在我的机器上,我现在在我的当前文件夹中有这个:
ZipFileContents.png

使用我们的档案建立一个DLL与CMake

一旦我们有了存档,我们就可以把它交给我们的朋友来编译。首先解压缩归档文件及其子归档文件。这会产生一个目录树,看起来像这样:
C:\work> dir /B C:\work \myCornerFinderExample
mlrFiles
mlrFiles.zip
sDirFiles
sDirFiles.zip
方法从Windows中的命令行创建DLL忍者工具Visual Studio2019工具:
C:\work> cmake -G Ninja -B ./build -DCMAKE_BUILD_TYPE=Release -DMATLAB_ROOT=。/myCornerFinderExample/mlrFiles/R2022b -S ./myCornerFinderExample/sDirFiles/codegen/dll/cornerFinder . dll . dll
C:\work> cmake—build build
这将创建拐角finder_win64 .dll和拐角finder_win64 .lib。这些将在。\build\codegen\dll\cornerFinder目录中。

创建一个简单客户端应用程序

现在我们的朋友已经构建了动态库,他们可以通过上面标题中所示的cornerFinder例程从c++程序中调用它。这段代码名为myClientCode.cpp,其核心是对拐角查找器函数的调用。感兴趣的线在这里:
/*将入口点称为“拐角查找器”。* /
emxInitArray_real32_T (x, 2);
拐角查找器(imFileName_data, imFileName_size, qFac, X, &valid);
...
//释放图像数组
emxDestroyArray_real32_T (X);
前两行创建一个存储角的数组并运行检测器。最后一行释放点数组。
现在我们的朋友为客户端代码创建了一个CMakeLists.txt文件。它是这样的:
cmake_minimum_required(版本3.12)
项目(MyClient)
集(CMAKE_CXX_STANDARD 14)
add_executable (myClient myClientCode.cpp)
target_include_directories (myClient私人
. . / myCornerFinderExample / sDirFiles codegen / dll / cornerFinder
../ myCornerFinderExample / mlrFiles / R2022b /走读生/包括)
target_link_directories(myClient PRIVATE ../build/codegen/dll/cornerFinder . dll
. . / myCornerFinderExample / mlrFiles / R2022b /走读生/ lib / win64 /微软/
. . / myCornerFinderExample / mlrFiles / R2022b /工具箱/视觉/内置/ src / ocvcg / opencv / win64 / lib
target_link_libraries(myClient PRIVATE)
客户端应用程序的构建与前面步骤中的DLL类似。在ClientCode目录的命令行中,我们的朋友执行了这些命令:
C:只\work\ClientCode> cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release
C:\work\ClientCode> cmake—build build
这将生成myClient.exe。一旦生成的和依赖的dll被添加到PATH环境变量中,就可以执行客户端程序来生成:
C:\work\build\codegen\dll\cornerFinder;%PATH%
C:\work\myCornerFinderExample\mlrFiles\R2022b\bin\win64\;%PATH%
C: \ \工作ClientCode > \制造\ myClient.exe
找到了一些角落!
点数:31 * 2
31.19 - 135.873
...
247.013 - 188.08
(这里,为了简洁起见,我们删除了输出数据的第一行和最后一行。)

访问本示例

本例中的文件可以通过MathWorks文件交换

现在轮到你了

告诉我们你是如何使用packNGo和代码构建工具的。
©2023 The MathWorks, Inc.
|
  • 打印
  • 发送电子邮件

댓글

댓글을남기려면링크를클릭하여MathWorks계정에로그하거나계정을새로만드십시오。