2014-03-27 46 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作为参数并将其转换为这些变体之一。