justHelloWorld
justHelloWorld

Reputation: 6828

OpenCV: L1 normalization of descriptor matrix

I'm trying to implement SIFTRoot in C++ following this article.

In particular:

    # 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)

My question are:

  1. Is there any built-in C++ function to do this in OpenCV?
  2. Are all the descriptors value positive? Otherwise the L1 norm should use the abs of each element.
  3. The first line means "for each row vector, compute the sum of all its elements, then add eps (in order to avoid to divide by 0) and finally divide each vector element by this sum value".

Upvotes: 1

Views: 1527

Answers (1)

cxyzs7
cxyzs7

Reputation: 1227

The SIFT descriptor is basically a histogram, so it shouldn't have negative values. I don't think there exists a single function in OpenCV that does what you want to achieve. But it's not too hard to come up with a few lines that do the job

// 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);

I don't know exactly how OpenCV deals with zero sum in L1 normalization. You can replace cv::normalize with descs.rows(i) /= (cv::norm(descs.rows(i), cv::NORM_L1) + eps) if the above code generates NaN.

Upvotes: 3

Related Questions