2014-03-27 76 views
0

我正在編寫一個代碼,通過在OPENCV中使用SURF從2個圖像中提取特徵及其描述符。描述符用於匹配兩個圖像的特徵。爲了計算最佳匹配,我計算了dotproduct並找出兩個特徵描述符矩陣之間的角度。我在acos函數中遇到錯誤。我已經添加了代碼和下面的錯誤..opencv中的acos函數錯誤

任何人都可以在程序中提示錯誤。

int main(int argc, char** argv) 
{ 
     //-- Step 1: Detect the keypoints using SURF Detector 
     int minHessian = 400; 

     SurfFeatureDetector detector(minHessian,1,3,false,true); 

     std::vector<KeyPoint> keypoints_1, keypoints_2; 

     detector.detect(img_1, keypoints_1); 
     detector.detect(img_2, keypoints_2); 


     // computing descriptors 
     SurfDescriptorExtractor extractor(minHessian,1,1,1,0); 
     Mat descriptors1, descriptors2; 
     extractor.compute(img_1, keypoints_1, descriptors1); 
     extractor.compute(img_2, keypoints_2, descriptors2); 

     std::cout << descriptors1.rows << std::endl; 
     std::cout << descriptors1.cols << std::endl; 
     std::cout << descriptors2.rows << std::endl; 
     std::cout << descriptors2.cols << std::endl; 

     Mat a; 
     Mat b(descriptors2.rows,descriptors2.cols, CV_32F); 
     a=descriptors1; 
     b=descriptors2; 

     Mat m; 
     if(((descriptors2.rows)||(descriptors1.rows))==0) 
     { 
       m.push_back(0); 
       return 0; 
     } 

     Mat des2t; 
     std::cout << des2t.rows << std::endl; 
     std::cout << des2t.cols << std::endl; 


     des2t= b.t(); 
     std::cout << des2t.rows << std::endl; 
     std::cout << des2t.cols << std::endl; 

     m= Mat::zeros(descriptors1.rows,1,CV_32F); 


     Mat dotprod = a*des2t; 
     Mat angle ; 

     angle = std::acos(dotprod); 

     std::cout << dotprod.rows << std::endl; 
     std::cout << dotprod.cols << std::endl; 

     return 0; 
} 

錯誤:

In function ‘int main(int, char**)’: 
surf.cpp:116:29: error: no matching function for call to ‘acos(cv::Mat&)’  
surf.cpp:116:29: note: candidates are: 
/usr/include/i386-linux-gnu/bits/mathcalls.h:55:1: note: double acos(double) 
/usr/include/i386-linux-gnu/bits/mathcalls.h:55:1: note: no known conversion for argument 1 from ‘cv::Mat’ to ‘double’ 
/usr/include/c++/4.6/cmath:102:3: note: float std::acos(float) 
/usr/include/c++/4.6/cmath:102:3: note: no known conversion for argument 1 from ‘cv::Mat’ to ‘float’ 
/usr/include/c++/4.6/cmath:106:3: note: long double std::acos(long double) 
/usr/include/c++/4.6/cmath:106:3: note: no known conversion for argument 1 from ‘cv::Mat’ to ‘long double’ 
/usr/include/c++/4.6/cmath:112:5: note: template<class _Tp> typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::acos(_Tp) 
make[2]: *** [CMakeFiles/surf.dir/surf.cpp.o] Error 1 
make[1]: *** [CMakeFiles/surf.dir/all] Error 2 
make: *** [all] Error 2 
+0

有沒有什麼方法可以將關鍵點的數量限制在100以內,並且根據它們的強度排列關鍵點? –

回答

3

您正在試圖ACOS適用於CV ::墊目標而不是雙,這是你的錯誤。

我從來沒有使用SURF在OpenCV中,所以我不能就與此有關代碼的有效性發表評論,但你應該嘗試並獲得墊dotprod的第一個元素,並傳遞一個ACOS。

如果dotprod不是1x1矩陣,那麼可能在您的代碼中存在一些問題。

要獲取爲0x0的元素dotprod,你可以做到以下幾點:被用來存儲它的元素

dotprod.at<double>(0,0); 

需要注意的是雙重需要與數據類型dotprod被替換,這可能與雙重不同。

+0

我按如下方式對程序進行加固。但是我遇到了分段錯誤。什麼是錯誤? (j = 0; j

+0

墊子的底層數據類型可能不是雙倍。檢查以查看確切的數據類型並將其用作at的模板參數。您可以通過運行dotprod來查看數據類型。鍵入(),然後根據OpenCV文檔檢查該常量。 –

+0

我得到了一個恆定的值5. –

2

由於dotprod是一個矩陣,因此沒有過載(對編譯器可見),它會生成矩陣的每個元素的反餘弦。如果矩陣是1x1矩陣,那麼您需要將矩陣的元素傳遞給acos()acos(dotprod[0][0])或某些類似的表示法。

2

的std :: ACOS()具有低於4點的變體:

  1. 浮子ACOS(浮動ARG);
  2. double acos(double arg);
  3. long double acos(long double arg);
  4. 雙ACOS(積分ARG)的這些

無取CV ::墊作爲參數。你需要編寫你自己的包裝器,它將cv :: Mat作爲參數並將其轉換爲這些變體之一。