SwisTrack/版本 3/贡献
此页面引用的是 SwisTrack 的版本 3。 除非您仍在使用此旧版本,否则您可能希望阅读SwisTrack 最新版本的文档。
SwisTrack 是用 C++ 编写的,应该可以在 Windows、Linux 和 MacOS 平台上编译。
SwisTrack 被分成三个部分
- 跟踪核心负责图像采集和分析
- 一个图形用户界面,提供用于可视化跟踪过程的不同步骤的工具
- 一个命令行界面
这三个部分通过 XML 描述链接在一起,该描述可以在 SwisTrack 目录中的 swistrack.exp 文件中找到。在这里,跟踪过程中的不同过程被组织成具有不同模式的组件(参见 使用 SwisTrack)。例如,对于组件input,合适的模式是来自相机的图像采集或来自文件。
基于此描述(它还指定了参数类型,例如列表或整数),GUI 提供了相应的控件来修改每个参数并将其存储到配置文件中,配置文件是swistrack.exp 的一个子集(例如,示例目录中的 example.cfg)。此外,GUI 还提供了一些面板,允许在跟踪期间更改参数,并同时观察它们对跟踪结果的影响(参见 使用 SwisTrack)。
另一方面,swistrack.exp 中定义的结构应该反映跟踪核心的类层次结构。一般来说,swistrack.exp 中的每个组件都封装在它自己的类中,而模式则是使用类成员函数中的switch语句实现的。在此,程序员有义务在每个类的构造函数中验证当前操作模式及其参数是否在实际的配置文件中提供,并在没有提供的情况下抛出异常。
参见 安装 SwisTrack 以获取有关设置开发者环境的信息。
swistrack.exp 中的 <COMPONENTS> 部分描述了在跟踪核心 中实现的需要用户输入参数的不同跟踪步骤。
<COMPONENTS> <INPUT desc="Input"/> <SEGMENTER desc="Segmenter"/> <SEGMENTERPP desc="Segmenter Post-Processing"/> <PARTICLEFILTER desc="Particle Filter"/> <MASK desc="Mask"/> <TRACKER desc="Tracker"/> <CALIBRATION desc="Calibration"/> <OUTPUT desc="Output"/> </COMPONENTS>
例如,<SEGMENTER> 部分可能包含 2 种模式(在本示例中)
<SEGMENTER mode="0" desc="Static Background, fixed threshold" long="The image is segmented by subtracting a static background image from every frame in the video. The 'Threshold' determines the minimal difference for the gray value of an object to be recognized, and 'Max. Number' is the maximal number of contours processed (sorted by size)."> <THRESHOLD desc="Threshold" type="integer" min="1" max="150" variable="1">20</THRESHOLD> <FIXED desc="Fixed" type="boolean" variable="1">0</FIXED> <BGIMAGE desc="Background Image" type="open" param="*.bmp">example/bg.bmp</BGIMAGE> </SEGMENTER> <SEGMENTER mode="1" desc="Running Average" long="The image is segmented by subtracting a static background image from every frame in the video. The 'Threshold' determines the minimal difference for the gray value of an object to be recognized, and 'Max. Number' is the maximal number of contours processed (sorted by size). 'Alpha' is the speed of the exponential averager."> <THRESHOLD desc="Threshold" type="integer" min="1" max="150" variable="1">20</THRESHOLD> <ALPHA desc="Averaging Speed" type="double" min="0" max="1" variable="1">0.02</ALPHA> </SEGMENTER>
这里模式 0 有三个参数(<THRESHOLD>、<FIXED> 和 <BGIMAGE>),而模式 1 则有两个参数(<THRESHOLD>、<ALPHA>),它们类型不同。例如,<BGIMAGE> 的类型 "open" 带有属性 param="*.bmp",告诉 GUI 使用打开文件控件(开发者应该在应用程序中保留一个字符串变量)。
在源代码中,分段器组件可以在 Segmenter 类中找到(segmenter.cpp、segmenter.h)。然后构造函数需要如下所示
if(!IsAttrByXPath(cfgRoot,"/CFG/COMPONENTS/SEGMENTER","mode")) throw "[Segmenter::Segmenter] Segmenter mode undefined (/CFG/COMPONENTS/SEGMENTER)"; mode=GetIntAttrByXPath(cfgRoot,"/CFG/COMPONENTS/SEGMENTER","mode"); switch(mode) { case 0 : { CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='0']"); CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='0']/BGIMAGE"); CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='0']/THRESHOLD"); CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='0']/FIXED"); } case 1 : { CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='1']"); CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='1']/THRESHOLD"); CreateExceptionIfEmpty(cfgRoot,"/CFG/SEGMENTER[@mode='1']/ALPHA"); } default : throw "[Segmenter::Segmenter] Segmenter mode not implemented"; } SetParameters();
参数本身是在成员函数 SetParameters() 中查询的,该函数将在用户在运行时更改参数时被调用。
下载所有必要的库包后(不要忘记使用您的开发环境编译它们),为 SwisTrack 核心创建一个项目。然后为 SwisTrack GUI 创建一个项目,它将核心与其他库链接在一起。确保将这两个项目都编译为多线程 DLL。
您需要链接以下库
- libxml++.lib
- libxml2.lib
- wxbase26_net.lib
- wxmsw26_adv.lib
- wxmsw26_core.lib
- wxbase26.lib
- wxtiff.lib
- wxjpeg.lib
- wxpng.lib
- wxzlib.lib
- wxregex.lib
- wxexpat.lib
- winmm.lib
- comctl32.lib
- rpcrt4.lib
- wsock32.lib
- oleacc.lib
- odbc32.lib
- objecttracker.lib
- 1394camera.lib
- cv.lib
- highgui.lib
- cxcore.lib
- vispolygon_dll.lib
- libgeom_dll.lib
本节介绍如何通过通过新模式扩展组件或通过添加新组件来扩展 SwisTrack 的核心功能。
- 在 swistrack.cfg 中添加一个新部分,并将 mode 属性设置为尚未使用的数字。还要指定模式的描述及其参数
- 在代表要扩展的组件的类的构造函数中的 switch(mode) 语句中添加您的模式,并为每个缺失的参数抛出异常
- 在类接口的 private 部分定义相应的变量(可以在 .h 文件中找到)
- 在 SetParameters() 成员函数中的 switch(mode) 语句中添加您的模式,以从 XML 描述中获取参数
- 遍历您正在扩展的类的每个成员函数,并将代码添加到 switch 语句中,以便实现您想到的功能。如果某些功能是冗余的,您可能希望将您的 'case' 语句放在表示您功能的 case 下,并删除其 'break;' 语句(不要忘记在您的 case 中添加一个 break; 虽然)
- 查看其他组件以了解它们的实现方式
- 从 'Component' 类继承您的类,包括 component.h,它还包含一些用于访问 XML 结构的便捷宏
- 您的类应该在位于您的组件上方的类中实例化;反过来,您的类需要实例化位于功能层次结构中您的组件下方的类