ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
int _iniThFAST, int _minThFAST): // 特征点数目,缩放因子(1.2),金字塔层数(8),
//角点的阈值,降低后的阈值(若无角点,降低阈值后继续提取)
nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
iniThFAST(_iniThFAST), minThFAST(_minThFAST)
{
// 开辟存放各层级缩放因子的容器
mvScaleFactor.resize(nlevels);
// 开辟存放各缩放因子平方的容器
mvLevelSigma2.resize(nlevels);
// 初始化容器内容
mvScaleFactor[0]=1.0f;
mvLevelSigma2[0]=1.0f;
// 计算各层级的缩放因子和平方
for(int i=1; i<nlevels; i++)
{
mvScaleFactor[i]=mvScaleFactor[i-1]*scaleFactor;
mvLevelSigma2[i]=mvScaleFactor[i]*mvScaleFactor[i];
}
//开辟缩放因子和其平方倒数的容器
mvInvScaleFactor.resize(nlevels);
mvInvLevelSigma2.resize(nlevels);
// 计算各层级的缩放因子和平方的倒数
for(int i=0; i<nlevels; i++)
{
mvInvScaleFactor[i]=1.0f/mvScaleFactor[i];
mvInvLevelSigma2[i]=1.0f/mvLevelSigma2[i];
}
// 开辟图像金字塔层级的容器
mvImagePyramid.resize(nlevels);
// 开辟存放各层特征点个数的容器
mnFeaturesPerLevel.resize(nlevels);
// 缩放因子的倒数
float factor = 1.0f / scaleFactor;
// 第0层分配的特征点数
float nDesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)pow((double)factor, (double)nlevels));
// 总共被分配过的特征点数量,用于后续分配最后一层的特征点
int sumFeatures = 0;
// 用第0层的特征点数来依次计算除最后一层以外的每层特征点数
for( int level = 0; level < nlevels-1; level++ )
{
mnFeaturesPerLevel[level] = cvRound(nDesiredFeaturesPerScale); // 四舍五入,返回int类型
sumFeatures += mnFeaturesPerLevel[level];
nDesiredFeaturesPerScale *= factor;
}
// 因为前面用了四舍五入,将剩余的所有特征点放在最后一层
mnFeaturesPerLevel[nlevels-1] = std::max(nfeatures - sumFeatures, 0);
// 定义成员变量为512,因为描述子储存坐标是256*4,描述子成对出现,所以为(256*4)/2
const int npoints = 512;
// 将int类型的bit_pattern_31_,强制转换为指针类型
const Point* pattern0 = (const Point*)bit_pattern_31_;
// 将pattern0到pattern0 + npoints的元素复制追加到pattern末尾
// 每段pattern0 + npoints中有一对描述子,所以占2个int类型
std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
//This is for orientation
// pre-compute the end of a row in a circular patch
// 本函数难点,这部分代码实际作用是求灰度圆的边界
// 开辟vmax的容器
umax.resize(HALF_PATCH_SIZE + 1); // HALF_PATCH_SIZE = 15;
// 创建循环辅助变量,v,v0,创建int类型vmax
int v, v0, vmax = cvFloor(HALF_PATCH_SIZE * sqrt(2.f) / 2 + 1); // cvFloor()向上取最小整数值
int vmin = cvCeil(HALF_PATCH_SIZE * sqrt(2.f) / 2); // 向下取最大整数值
// hp2等于半径的平方
const double hp2 = HALF_PATCH_SIZE*HALF_PATCH_SIZE;
// 保持对称性
for (v = 0; v <= vmax; ++v)
umax[v] = cvRound(sqrt(hp2 - v * v));
// Make sure we are symmetric
for (v = HALF_PATCH_SIZE, v0 = 0; v >= vmin; --v)
{
while (umax[v0] == umax[v0 + 1])
++v0;
umax[v] = v0;
++v0;
}
}
三、函数的传参
1. int _nfeatures 特征点的数目,类型为int类型
2. float _scaleFactor 缩放因子,类型为float类型
3. int _nlevels 金字塔的层数,类型为int类型
4. int _iniThFAST 提取角点的阈值,类型为int类型
5. int _minThFAST 降低后的阈值(若无角点,降低阈值后继续提取),类型为int类型