C++ OpenCV SIFT描述符关键点半径
我在钻研。我发现了一些令人费解的代码来获取兴趣点邻域的半径。下面是带注释的代码,其中变量名称更改为更具描述性:C++ OpenCV SIFT描述符关键点半径,c++,opencv,sift,C++,Opencv,Sift,我在钻研。我发现了一些令人费解的代码来获取兴趣点邻域的半径。下面是带注释的代码,其中变量名称更改为更具描述性: // 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
// 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);
//将倍频程保持在256以下(255是1111111)
int倍频程=kpt.octave&255;
//如果倍频程>=128。。。????
倍频程=倍频程<128?倍频程:(-128 |倍频程);
//1/2^绝对值(八度)
浮动音阶=倍频程>=0?1.0f/(1)
我不懂前三行
实际上,此SIFT实现对关键点倍频程属性中的多个值进行编码。如果参考,您可以看到:
kpt.octave = octv + (layer << 8) + (cvRound((xi + 0.5)*255) << 16);
此映射在以下位置计算:
因此,上面的第二行只是映射这些值的一种方法:
octave = 255 => -1
octave = 0 => 0
octave = 1 => 1
..
第三行只是计算音阶的一种方法,考虑到负八度音阶给出的音阶大于1,例如1谢谢你的详细解释!只有一件事我还不太明白:通常情况下,关键点不应该在最高音阶处被检测到(还记得检查26个邻域的极值吗,它们是周围的像素和下一个尺度中的邻域?)那么为什么在这里SIFT生成了尺度为2(倍频程-1)的关键点呢?
kpt.octave = (kpt.octave & ~255) | ((kpt.octave + firstOctave) & 255);
octave = 255 => -1
octave = 0 => 0
octave = 1 => 1
..