Quick Start
本教程旨在通过一些想法,目标等有趣的例子让你熟悉OpenBr。注意这部分教程需要你有个网络摄像头。
OpenBr是一个建立在Qt,Opencv,Eigen上的C++库。它不仅可以通过命令行使用br应用,而且可以使用C/C++ API接口。使用br应用是最简单和快速的方法入门,而且本教程将在所有的例子中使用。
首先确保在你的操作系统已经安装OpenBr,详情参见安装部分。
打开你的终端和命令提示符输入以下命令:
$ br -gui -algorithm "Show(false)" -enroll 0.webcam
如果一切按计划进行,你的摄像头将打开并捕捉视频。恭喜你,已经在使用OpenBr了。
让我们讨论以上的命令发生了什么。-gui, -algorithm,-enroll 都是OpenBR 指定参数选项的例子。OpenBr的参数选项是以 - 开始,选项参数跟在 - 后,通过空格分开。标签选项通常需要指定数目的参数,所有的参数选项和值都记录在这里。下面简单介绍上面几个选项。
-gui //这个标签用来告诉OpenBR打开一个GUI窗口。注意应以第一个参数传给br。
-algorithm //是一个在Openbr中很重要的参数,它期望一个参数,用来表示算法的字符串。这个字符串决定哪个图片,元数据传输到管道中。
-enroll //在相册中读入文件,从算法管道接收然后转换为其他的格式文件。-enroll 选项接收一个输入参数和一个可选的输出参数。OpenBr支持多种格式,包括.jpg,.png,.csv,.xml,.webcam表示电脑摄像头。
让我们试一下稍微复杂一点的例子。重新打开终端输入下面的命令:
$ br -gui -algorithm "Cvt(Gray)+Show(false)" -enroll 0.webcam
我们把普通RGB图像通过在算法字符串中添加Cvt(grey)选项转换成灰度图。Cvt是convert的缩写,这是一个OpenBR变换的例子,show选项也是一样。实际上每一个算法字符串仅仅是添加到管道的一个变换序列。
通常情况,变换接受参数,我们指定Gray给Cvt作为一个运行时参数告诉Transform把图像转换为哪个颜色空间。我们也可以通过Cvt(HSV)或Cvs(LUV)转换成HSV,LUV颜色空间。参数可以用键值对的形式,也可以简写(Cvt(Gray)和Cvt(colorSpace=Gray))。
接下来看看脸部识别在OpenBr中的应用。回到终端输入:
$ br -gui -algorithm "Cvt(Gray)+Cascade(FrontalFace)+Draw(lineThickness=3)+Show(false)" -enroll 0.webcam
你的摄像头将重新打开,但是这次一个边界框出现在你的脸部周围。我们加了两个Transforms到算法字符串:Cascade和Draw.下面介绍下这个变换以及如何使用:
- Cvt(Gray):转换图片的颜色空间从RGB到灰度。灰度使级联更好的工作。
- Cascade(FrontalFace):这是一个OpenCV级联分类器的包装。它使用FrontFace模型去分类正脸。
- Draw(lineThickness=3):在摄像头视频帧中画矩形。lineThickness决定了矩形的边框。
- Show(false):在GUI窗口中显示图像。false表明不需要等待按键。
每一个变换完成后将输出传递到下一个变换。你可以传递任意想要进行的变换。但是某些变换需要特定的输入。
你或许想知道什么样的对象真正可以通过算法管道传输。下面有两种对象可以在OpenBR中处理:
- 文件
- 模板文件。
如果你想学习更多命令行或所有的插件和键的数据结构,请参照文档。下面将深入讲解OpenBR的使用。
Algorithms in OpenBR
OpenBR一个优点就是稳定简单。在OpenBR中,一个算法字符串定义了一个输入图像操作的方法和(可选)一个比较它们的方法。
不是从原始图像开始比较,通常是在优化过的显示或一个正在进行的任务的图像模板。我们为了清晰起见,Openbr对象模板从这个概念得到名字,模板是更通用的生物特征概念。生成这种优化表示的过程被称为模板输入或模板生成。给定两个模板,模板比较它们之间的相似性,其中最高值表示大的匹配度。操作上,通常期望产生较小,精确,快速的比较模板。
像之前提到的一样,一个算法在OpenBR中通过算法字符串定义。强制定义的算法字符串有以下几大优点。
- 通过强行解耦每一个算法步骤,便利的修改和重用能够确保好的软件开发实践
- 免去了很多重复的头文件
- 运行算法参数调整而无需重新编译
- 明确。
OpenBR提供了设置插件的属性值和创建简洁的算法字符串语法。以下是相关的符号标记:
Symbol | Meaning |
---|---|
PluginName(property1=value1,...propertyN=valueN) | 一个通过名字和属性和值的列表的描述。如不指定属性将使用默认值 |
: | 分割 |
+ | 管道的缩写,将输入的对象进行序列化,将左侧的输出结果作为右侧的输入 |
/ | |
{} | |
<> | |
() | 操作顺序分割用 |
接下来看看代码库的组成部分:
在openbr/core/core.cpp文件的AlgorithnmCore::init()方法中,你可以在冒号处分割算法描述的代码。此后,这个函数中我们使用make生成模板,比较对象。这里的make在公共C++ API中定义,我们也可以在最终用户代码中调用。
接下来我们讨论一些关于在openbr/openbr_plugin.cpp文件的Transform::make函数源码。注意,make函数与其他plugin类型相同,而且不会被覆盖。
其中的第一步是转换模板生成描述到Transforms,替换像+这样的操作符,下面是代码:
{ // Check for use of '+' as shorthand for Pipe(...)
QStringList words = parse(str, '+');
if (words.size() > 1)
return make("Pipe([" + words.join(",") + "])", parent);
}
操作符展开之后,模板描述将形成一个树的结构,然后Transform将递归这个描述,从根开始:
Transform *transform = Factory<Transform>::make("." + str);
让我们以sripts/helloworld.sh文件作为一个例子:
Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(128,128,0.33,0.45)+CvtFloat+PCA(0.95):Dist(L2)