OpenCV SIFT 描述符关键点半径

2024-05-19

我正在深入研究OpenCV的SIFT描述符提取的实现 https://github.com/Itseez/opencv/blob/master/modules/nonfree/src/sift.cpp。我发现了一些令人费解的代码来获取兴趣点邻域的半径。下面是带注释的代码,变量名称已更改为更具描述性:

// keep octave below 256 (255 is 1111 1111)
int octave = kpt.octave & 255;
// if octave is >= 128, ...????
octave = octave < 128 ? octave : (-128 | octave);
// 1/2^absval(octave)
float scale = octave >= 0 ? 1.0f/(1 << octave) : (float)(1 << -octave);
// multiply the point's radius by the calculated scale
float scl = kpt.size * 0.5f * scale;
// the constant sclFactor is 3 and has the following comment:
// determines the size of a single descriptor orientation histogram
float histWidth = sclFactor * scl;
// descWidth is the number of histograms on one side of the descriptor
// the long float is sqrt(2)
int radius = (int)(histWidth * 1.4142135623730951f * (descWidth + 1) * 0.5f);

我知道这与转换为获取兴趣点的比例有关(我已阅读 Lowe 的论文),但我无法将这些点连接到代码。具体来说,我不明白前三行和最后一行。

我需要理解这一点才能为运动创建类似的局部点描述符。


我不明白前 3 行

事实上这个 SIFT 实现encodes内的几个值KeyPoint octave属性。如果您参考line 439 https://github.com/Itseez/opencv/blob/173442bb2ecd527f1884d96d7327bff293f0c65a/modules/nonfree/src/sift.cpp#L439你可以看到:

kpt.octave = octv + (layer << 8) + (cvRound((xi + 0.5)*255) << 16);

这意味着八度音程存储在第一个字节块中,层存储在第二个字节块中,等等。

So kpt.octave & 255(可以在unpackOctave方法)只是屏蔽关键点八度音程以检索有效八度音程值。

另外:此 SIFT 实现使用负的第一个八度音程(int firstOctave = -1)以处理更高分辨率的图像。由于八度音阶索引从 0 开始,因此计算映射:

octave index = 0 => 255
octave index = 1 => 0
octave index = 2 => 1
...

该映射是在以下位置计算的line 790 https://github.com/Itseez/opencv/blob/173442bb2ecd527f1884d96d7327bff293f0c65a/modules/nonfree/src/sift.cpp#L790:

kpt.octave = (kpt.octave & ~255) | ((kpt.octave + firstOctave) & 255);

因此上面的第二行只是映射回这些值的一种方法:

octave = 255 => -1
octave = 0   => 0
octave = 1   => 1
..

第三行只是计算音阶的一种方法,考虑到负八度给出的音阶 > 1,例如1 << -octave给出 2 为octave = -1这意味着它的大小增加了一倍。

[我不明白]最后一行。

基本上它对应于包裹尺寸平方块的圆的半径D,因此sqrt(2)并除以 2。D通过乘法计算:

  • 关键点尺度,
  • 放大倍数 = 3,
  • 描述符直方图的宽度 = 4,向上舍入到下一个整数(因此为 +1)

事实上,您可以在其中找到详细的描述vlfeat 的 SIFT 实现 https://github.com/vlfeat/vlfeat/blob/38a03e12daf50ee98633de06120834d0d1d87e23/vl/sift.c#L1948:

每个空间仓的支持度扩展为SBP = 3sigma 像素,其中 sigma 是关键点的比例。因此所有的 bin 一起具有支持 SBP x NBP 像素宽。自从 使用像素加权和插值,支持扩展 另一个半箱。因此,支撑体是一个方形窗口 SBP x (NBP + 1) 像素。最后,由于补丁可以 任意旋转,我们需要考虑一个窗口 2W += sqrt(2) x SBP x (NBP + 1) 像素宽。

最后强烈推荐大家参考一下这个vlfeat SIFT 文档 http://www.vlfeat.org/api/sift.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV SIFT 描述符关键点半径 的相关文章

  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • json.net自定义jobject反序列化

    我正在尝试使用 JsonConvert DeserializeObject string 将字符串反序列化为可与动态一起使用的 jobject 来动态访问 json 文档 但是我想避免知道文档的大小写 以便我可以输入 dynamic doc
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • 从模板切换传递的类型

    在 C 中是否可以检查传递给模板函数的类型 例如 template
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • 在谷歌C​​olab中使用cv2.imshow()

    我正在尝试通过输入视频来对视频进行对象检测 cap cv2 VideoCapture video3 mp4 在处理部分之后 我想使用实时对象检测来显示视频 while True ret image np cap read Expand di
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐