我目前正在使用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)
Where the bit_pair_test is the bit value that has been calculated from the test for a pair of test points. The final result is something like (for a set of binary tests (...,0,1,0,1,1)):
(20*1) + (21*1) + (22*0) + (23*1) + (24*0) + ...
现在,OpenCV的ORB是如何存储这些位串的对我来说是一个谜。如果我们查看包含整个图像描述符的矩阵,每行都是单个关键点的单个描述符,我们可以看到每个描述符有32个8位数字,总共有256个位用于存储信息,这就是BRIEF-32所使用的。我不明白为什么要将这256位拆分为32个字节。官方文档(http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_brief/py_brief.html)只说OpenCV以字节存储这些描述符,但没有解释为什么这样做。我考虑了三种可能性,但不能排除其中某些组合可能是答案:
BRIEF(ORB版本)的工作原理如下:我们取一个31x31像素的块(表示一个特征),并创建一堆随机的5x5像素测试点。然后我们取这些点的成对,根据第一个点的强度是否大于或小于等于第二个点的强度进行评估,得出一个二进制决策(0或1)。然后我们取所有这些位并使用基本求和公式构建长度为n的二进制字符串(对于BRIEF-32,我们有32字节* 8 = 256位长的二进制字符串):
SUM(2^(i-1)*bit_pair_test)
Where the bit_pair_test is the bit value that has been calculated from the test for a pair of test points. The final result is something like (for a set of binary tests (...,0,1,0,1,1)):
(20*1) + (21*1) + (22*0) + (23*1) + (24*0) + ...
现在,OpenCV的ORB是如何存储这些位串的对我来说是一个谜。如果我们查看包含整个图像描述符的矩阵,每行都是单个关键点的单个描述符,我们可以看到每个描述符有32个8位数字,总共有256个位用于存储信息,这就是BRIEF-32所使用的。我不明白为什么要将这256位拆分为32个字节。官方文档(http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_brief/py_brief.html)只说OpenCV以字节存储这些描述符,但没有解释为什么这样做。我考虑了三种可能性,但不能排除其中某些组合可能是答案:
- 我看不到某些存储技术
- 计算二进制字符串的汉明距离时存在性能问题,长度为256位(在我们的情况下)
- 匹配过程中的优化 - 匹配基本上是将一个图像中关键点的描述符与第二个图像中关键点的描述符进行比较。由于我们有二进制字符串,因此汉明距离在这里是显而易见的选择。可能每个子字符串都与第二个图像中另一个关键点的描述符中的相应子字符串进行比较(位置0处的子字符串(关键点X,图像1)与位置0处的子字符串(关键点Y,图像2))。最后,OpenCV可能会说:“好的,我们的描述符有80%的匹配率,因为大约26个子字符串在两个描述符中都相同,所以我们有一个赢家。”但我找不到任何证据来证实这一点。