KRTS使用 Dlib 进行机器学习指南
目录
简介
本指南将帮助您学习如何使用 Dlib 19.17 库在内核模式下进行实时图像处理。我们假设您基本上已经知道如何设置项目并打开驱动程序以开始您的工作。如果你对此不熟悉,你应该看看第一个项目教程。
Dlib 在内核层正在使用我们的实时 Windows 虚拟化。这种虚拟化在实时环境中模拟 Windows API 的最重要部分。只有在无法进行仿真或不合理的情况下,虚拟化才会离开实时环境并依赖于 Windows。此外,这种虚拟化是有限的,因此在实时使用Dlib时存在一些限制。
需求和支持的环境
Dlib 严重依赖标准的 C++ 库。这意味着与 Dlib 和 Dlib 库本身交互的代码必须使用完全相同的 C/C++ 运行时库 (CRT) 实例。KRTS不支持任何DLL版本的CRT用于内核模式。因此,要在 KRTS中使用 Dlib 库,它们必须使用静态链接的运行时构建为静态库。不能使用 Dlib 的 DLL 版本,因为这需要 Dlib 使用 CRT 的 DLL 版本。此外,当您将 CRT 的调试版本用于其中一个构建配置时,您还需要链接到静态 Dlib 库的调试版本。
Windows虚拟化仅适用于KRTS实时任务和作为DLL加载到内核模式的代码。对于Kithara RealTime Suite 10.11,我们已经成功地使用以下Visual Studio平台工具集(包括静态CRT)测试了Dlib 19.17:
- Visual Studio 2019 (vc16.3) (Visual Studio 2019 版本 16.3.3,更新 3)* Visual Studio 2019 (vc16.3) (Visual Studio 2019 version 16.3.3, Update 3)
这些测试是通过在实时环境中运行 dlib/test 目录中找到的所有 Dlib 测试来执行的。对于测试,Dlib 是使用默认设置构建的,除了作为静态库构建。请注意,Dlib 使用了 C++11 标准功能,这些功能仅在 Visual Studio 2015 之后才得到充分实现。
构建 Dlib 库
我们建议使用您将要用于自己的项目的编译器重新构建 Dlib 库。这不仅减少了出现兼容性问题的机会,而且还让您有机会完全从 Dlib 构建中删除一些不需要或不可用的功能。
Dlib 依赖于工具“CMake”为不同的编译器和 IDE 生成项目文件。请参阅 Dlib 文档,了解如何将 CMake 与 Dlib 一起使用。CMake 允许您配置构建并禁用对第三方库和 API 的特定依赖项。
使用 CMake 进行配置以与 KRTS一起工作
最重要的配置步骤是将 BUILD_SHARED_LIBS设置为禁用,因为它默认设置为“启用”。此外,请确保已启用 BUILD_WITH_STATIC_CRT。
我们还建议禁用有关 CUDA 和 GUI 支持的所有条目。这些 API 不能在内核模式下使用。
这可以通过 CMakeGUI 完成,如下所示:
-
DLIB_USE_CUDA = false
-
DLIB_NO_GUI_SUPPORT = true
-
将CMAKE_INSTALL_PREFIX设置为适当的目录,例如:D:\install\
-
要静态链接 CRT 运行时,请设置以下标志:
-
CMAKE_CXX_FLAGS_DEBUG = /MTd /Zi /Ob0 /Od /RTC1
-
CMAKE_C_FLAGS_DEBUG = /MTd /Zi /Ob0 /Od /RTC1
-
CMAKE_CXX_FLAGS_RELEASE = /MT /O2 /OB2 /DNDEBUG
-
CMAKE_C_FLAGS_RELEASE = /MT /O2 /Ob2 /DNDEBUG
请注意,默认值为 /MD…,即动态链接。如果要构建除 debug 或 release 之外的其他配置,也请适当设置其标志。完成后,单击“配置”、“生成”和“打开项目”。在 Visual Studio 界面中,设置所需的构建类型,例如 Release 和 x64。接下来,构建名为“INSTALL”的项目。在此示例中,您将在目录 D:\install\ 中找到您的生成输出。
使用 Dlib 库设置项目
除了设置内核模式 DLL 项目的默认方式外,您还需要将 Dlib 构建的包含目录添加到编译器设置的包含目录中,并将静态库的路径以及要使用的库添加到链接器设置中。包含文件将在安装目录中的“include”中找到,库位于“lib”中。需要以下库之一,具体取决于所需的生成配置:
-
dlib19.17.0_debug_64bit_msvc1923.lib
-
dlib19.17.0_release_64bit_msvc1923.lib
-
dlib19.17.0_debug_32bit_msvc1923.lib
-
dlib19.17.0_release_32bit_msvc1923.lib
请注意,后缀“msvc1923”是指用于构建 Dlib 的 Visual Studio 编译器。
请不要忘记仍然链接到KRTS库!如果您查看我们的示例,Dlib 的项目配置是通过使用属性表来解决的。这些设置将放入属性表中,实际项目将继承这些属性表,并且在 Visual Studio UI 中可能不可见。这为配置阶段提供了一些模块化。
运行 Dlib 代码
使用Kithara RealTime Suite实时运行Dlib代码需要两个主要步骤。首先,您需要将包含代码的DLL加载到内核模式。其次,您将需要一个实际运行代码的任务。
打开KRTS驱动程序后,可以立即加载DLL。KS_loadKernel,必须使用专用函数 KS_loadVisionKernel,而不是通常的函数。它将加载 DLL 并在适当的环境中执行其入口点。这是正确初始化 CRT 所必需的。
KSHandle hKernel;
KS_loadVisionKernel(&hKernel, “myDll.dll”, 0, 0, KSF_KERNEL_EXEC);
下一步是创建一个任务,为此,我们首先需要在加载的DLL内部创建一个函数的回调,其中包含任务的代码。
KSHandle hCallBack;
KS_createKernelCallBack(&hCallBack, hKernel, “myFunction”, 0,
KSF_DIRECT_EXEC |KSF_SAVE_FPU, 0);
DLL 中的函数在此处称为“myFunction”。必须使用标志 KSF_DIRECT_EXEC,才能在触发回调的同一上下文中运行回调。标志 KSF_SAVE_FPU 是必需的,以便还在上下文切换上保存 FPU 和 SSE 寄存器的状态。
关于结构包装和对齐的重要通知 |
---|
如果不使用默认结构打包,请确保包含具有相同结构打包效果的 Dlib 头文件,就像用于构建 Dlib 一样(通常具有 8 个字节的默认打包)。Dlib 头文件不强制执行特定的结构打包。结构打包不匹配将导致二进制文件不兼容,从而在运行时导致各种错误。 |
一个例子是我们的样本。它们使用与默认结构打包不同的结构打包,因此需要包含 Dlib 标头,并恢复默认结构打包。 |
在现在实际创建任务之前,我们还必须提高为其分配的堆栈空间。默认情况下,Windows 为每个线程保留 1 MB 的堆栈空间。KRTS只保留 3 KB,这对于像 Dlib 这样的库来说可能还不够。因此,我们将 KS_setTaskStackSize 的大小提高到 Windows 线程的典型大小。
KS_setTaskStackSize(0x100000, 0);
最后,我们创建任务。必须使用标志 KSF_CUSTOM_STACK_SIZE 创建任务,才能使用我们刚刚设置的更大的堆栈大小。
KSHandle hTask;
KS_createTask(&hTask, hCallBack, 250, KSF_CUSTOM_STACK_SIZE);
有关任务的更多信息,请参见 任务模块。
请注意,只有实际调用 Dlib 函数的函数才能作为任务执行。处理程序等的其他回调可以正常使用,并同时驻留在同一个 DLL 中。
限制和局限性
1.系统建议
由于所有分配都在非分页池中,因此内核级别的内存资源受到限制,而非分页池本身在 Windows 中是有限的资源。此问题对于 32 位 Windows XP 尤其适用,对于非分页池,其最大大小为 256 MBytes。对于 64 位版本或高于 XP 的版本,这些限制设置得更高,如果您安装了足够的物理内存,则不会造成问题。另请注意,许多数据结构需要连续内存。这在 32 位平台上可能很少见。
2.实时限制
某些 Dlib 操作无法实时执行,因为它们需要与 Windows 系统交互。这些是文件处理和用户交互(Windows、输入)等功能。这些操作需要与用户模式线程进行通信,但用户模式线程的优先级很高,但当然无法满足内核模式实时任务的实时约束。
3.不支持的功能和缺失的功能
以下功能不能在内核模式下使用:
-
GPU 加速(例如通过 CUDA)
-
以太网功能
-
使用图形用户界面
- 仅对用于呈现 UI 的功能的基本子集提供基本支持。我们不建议使用内核模式中的任何 GUI 元素。
DLib 编译
不方便编译,可以使用我们已经编译好的Dlib库
- 打开源码,选择VS2022 X64,设置编译输出路径,点击【Configure】
- 点击高级选项,设置编译选项 CRT
配置安装路径
其他属性配置
打开 VS进行编译
切换Debug/Release, 运行 【ALL_BUILD 】 ->运行 【INSTALL】
编译完成!