//這個成員函數重載了函數括號運算符,讓他具有函數的特點
//但是還不知道在其他程序塊是如何應用這塊代碼的。
//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());}
}
//按照上面的操作步驟是提取到每層圖像上的特征點之后直接就計算特征點的描述子,和將每層中提取的特征
//點的坐標還原到原圖像上去。而沒有先用四叉樹對提取的特征點進行優化。
?