1

在这篇文章之后,我正在尝试在 C++ 中实现 SIFTRoot 。

尤其是:

    # apply the Hellinger kernel by first L1-normalizing and taking the
    # square-root
    descs /= (descs.sum(axis=1, keepdims=True) + eps)
    descs = np.sqrt(descs)

我的问题是:

  1. 在 OpenCV 中是否有任何内置的 C++ 函数可以执行此操作?
  2. 所有描述符的值都是正的吗?否则 L1 范数应该使用每个元素的绝对值。
  3. 第一行的意思是“对于每个行向量,计算其所有元素的总和,然后添加 eps(为了避免除以 0),最后将每个向量元素除以这个总和值”。
4

1 回答 1

3

SIFT 描述符基本上是一个直方图,所以它不应该有负值。我认为 OpenCV 中不存在一个可以实现您想要实现的功能。但是想出几行来完成这项工作并不难

// For each row
for (int i = 0; i < descs.rows; ++i) {
  // Perform L1 normalization
  cv::normalize(descs.row(i), descs.row(i), 1.0, 0.0, cv::NORM_L1);
}
// Perform sqrt on the whole descriptor matrix
cv::sqrt(descs, descs);

我不确切知道 OpenCV 如何处理 L1 归一化中的零和。如果上面的代码生成 NaN,您可以替换cv::normalize为。descs.rows(i) /= (cv::norm(descs.rows(i), cv::NORM_L1) + eps)

于 2016-07-22T03:53:42.933 回答