//这个成员函数重载了函数括号运算符,让他具有函数的特点
//但是还不知道在其他程序块是如何应用这块代码的。
//InputArray和OutputArray是opencv中的两个函数接口
void ORBextractor::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,OutputArray _descriptors)
{ if(_image.empty())return;//将输入的图像转换为Mat数据类型Mat image = _image.getMat();//判断数据类型是不是8bits单通道类型assert(image.type() == CV_8UC1 );// Pre-compute the scale pyramid//先计算输入图像的金字塔ComputePyramid(image);//从金字塔中的每一层图像中获取所有的特征点都存储在allKeypoints向量中vector < vector<KeyPoint> > allKeypoints;ComputeKeyPointsOctTree(allKeypoints);//ComputeKeyPointsOld(allKeypoints);Mat descriptors;int nkeypoints = 0;//将每一层获取的特征点的个数累加for (int level = 0; level < nlevels; ++level)nkeypoints += (int)allKeypoints[level].size();if( nkeypoints == 0 )_descriptors.release();else{//OutputArray是InputArray的派生类,在使用_OutputArray.getMat()之前要先用create()来为 //矩阵分配内存。_descriptors.create(nkeypoints, 32, CV_8U);descriptors = _descriptors.getMat();}_keypoints.clear();_keypoints.reserve(nkeypoints);int offset = 0;for (int level = 0; level < nlevels; ++level){//首先获取每一层图像上提取的特征点vector<KeyPoint>& keypoints = allKeypoints[level];//统计每层图像上提取的特征点的个数int nkeypointsLevel = (int)keypoints.size();if(nkeypointsLevel==0)continue;// preprocess the resized image//每次将金字塔上某一层上的图像复制都workingMat中Mat workingMat = mvImagePyramid[level].clone();//对这个图像用高斯滤波器进行平滑,输出的图像仍然放在workingMat中的GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);//平滑之后计算描述子// Compute the descriptors//一个特征点的描述子占一行Mat desc = descriptors.rowRange(offset, offset + nkeypointsLevel);computeDescriptors(workingMat, keypoints, desc, pattern);//将所有层上的特征点的描述子都放在一起,每一行是一个描述子offset += nkeypointsLevel;// Scale keypoint coordinatesif (level != 0){//scale是金字塔中不同层图像所代表的尺度,越往上尺度越大float scale = mvScaleFactor[level]; //getScale(level, firstLevel, scaleFactor);//我们先前在提取金字塔中每一层图像中的特征点时,特征点的坐标都设置为了在当前图像//下的坐标,从第i-1层图像变为第i层图像,相当于将图像中每一个像素点的坐标除以1.2//所以为了得到每一层图像上提取的特征点在原图像中的坐标位置需要乘以1.2。for (vector<KeyPoint>::iterator keypoint = keypoints.begin(),keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)keypoint->pt *= scale;}// And add the keypoints to the output_keypoints.insert(_keypoints.end(), keypoints.begin(), keypoints.end());}
}
//按照上面的操作步骤是提取到每层图像上的特征点之后直接就计算特征点的描述子,和将每层中提取的特征
//点的坐标还原到原图像上去。而没有先用四叉树对提取的特征点进行优化。