我目前正在使用 OpenCV 的 ORB 特征提取器,我确实注意到 ORB 描述符的存储方式很奇怪(至少对我而言)(它基本上是一个 BRIEF-32,其修改与我的问题无关)。正如你们中的一些人所知,ORB 使用修改后的 FAST-9(圆半径 = 9 像素;还存储关键点的方向)提取关键点,并使用带有修改后的 BRIEF-32 描述符的那些来存储关键点表示的特征。
Brief(ORB 版本)的工作原理如下:我们采用一个 31x31 像素的补丁(代表一个特征)并创建一堆随机的 5x5 像素测试点。然后,我们取这些点对并评估它们的强度,从而根据对中第一个点的强度是否大于或小于第二个点的强度,得出二元决策(0 或 1)。然后我们获取所有这些位并使用基本的求和公式来构建长度为 n 的二进制字符串(对于 BRIEF-32,我们有 32 字节 * 8 = 256 位长的二进制字符串):
SUM(2 (i-1) *bit_pair_test)
其中 bit_pair_test 是我们从一对测试点的测试中计算出的位值。最终结果类似于(对于一组二进制测试 (...,0,1,0,1,1)):
(2 0 *1) + (2 1 *1) + (2 2 *0) + (2 3 *1) + (2 4 *0) + ...
现在,OpenCV 的 ORB 存储这些位串的方式对我来说是个谜。如果我们查看包含整个图像描述符的矩阵,其中每一行是单个关键点的单个描述符,我们可以看到每个描述符有 32 个 8 位数字,这总共导致了 BRIEF-32 使用的那些 256 位来存储信息。我不明白为什么我们将这 256 位分成 32 字节。官方文档(http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_brief/py_brief.html)只说OpenCV以字节为单位存储这些描述符,但它没有解释它为什么这样做。我考虑了三种可能性,但不排除这些可能性的某种组合可能是答案的可能性:
- 一些我看不到的存储技术
- 计算这么长的二进制字符串(在我们的例子中为 256 位)的汉明距离时的一些性能问题
- 匹配过程的优化 - 匹配基本上将一个图像中关键点的描述符与第二个图像中关键点的描述符进行比较。因为我们有二进制字符串汉明距离是这里的明显选择。可能是以某种方式将这 32 个子字符串中的每一个与第二个图像中另一个关键点的描述符中的对应项进行比较(位置 0 的子字符串(关键点 X,图像 1),位置 0 的子字符串(关键点 Y,图像 2)。最后可能是 OpenCV 说:“好吧,我们有 80% 的描述符匹配率,因为所有子字符串中有大约 26 个在两个描述符中是相同的)所以我们有一个赢家。” 但是,我找不到任何证据来证实这一点。