opencv中的acos函数错误

Posted

技术标签:

【中文标题】opencv中的acos函数错误【英文标题】:acos function error in opencv 【发布时间】:2014-03-27 06:00:25 【问题描述】:

我正在编写一个代码,通过在 OPENCV 中使用 SURF 从 2 个图像中提取特征及其描述符。描述符用于匹配两个图像的特征。为了计算最佳匹配,我计算了点积并找到了两个特征描述符矩阵之间的角度。我在 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

【问题讨论】:

有什么方法可以将关键点的数量限制在 100 个以内,并且关键点是根据其强度排序的吗? 【参考方案1】:

您正在尝试将 acos 应用于 cv::Mat 对象而不是双精度对象,这是您的错误。

我从未在 OpenCV 中使用过 SURF,因此我无法评论与此相关的代码的有效性,但您应该尝试获取 Mat dotprod 的第一个元素并将其传递给 acos .

如果 dotprod 不是 1x1 矩阵,那么您的代码中可能存在一些问题。

要在 dotprod 中获取 0x0 处的元素,您可以执行以下操作:

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

请注意,double 需要替换为 dotprod 用于存储其元素的数据类型,这可能与 double 不同。

【讨论】:

我改变了程序如下。但是我遇到了分段错误。错误是什么? for(i=0;i(i,j)=std::acos(dotprod.at (i,j)); 您的垫子的底层数据类型可能不是双倍的。检查以查看确切的数据类型并将其用作 at 的模板参数。您可以通过运行 dotprod.type() 查看数据类型,然后对照 OpenCV 文档检查该常量。 我得到了一个常数值 5。 好的,这是一个浮点数,用浮点数替换双精度:dotprod.at(0,0)。你可以在这里阅读更多关于 OpenCV 类型枚举的信息docs.opencv.org/modules/core/doc/… 是的,你没有初始化角度矩阵。需要做这样的事情: Mat angle(dotprod.rows, dotprod.cols, dotprod.type() )【参考方案2】:

由于dotprod 是一个矩阵,因此不会产生生成矩阵每个元素的反余弦的重载(编译器可见)。如果矩阵是 1x1 矩阵,则需要将矩阵的元素传递给 acos():acos(dotprod[0][0]),或类似的符号。

【讨论】:

【参考方案3】:

std::acos() 有以下 4 个变体:

    float acos(float arg); 双acos(双arg); long double acos( long double arg ); 双acos(整数arg)

这些都没有将 cv::Mat 作为参数。您需要编写自己的包装器,它将 cv::Mat 作为参数并将其转换为这些变体中的任何一个。

【讨论】:

以上是关于opencv中的acos函数错误的主要内容,如果未能解决你的问题,请参考以下文章

acos() 函数是不是有准确的近似值?

OpenCV 3 中的 PCA 错误

OpenCV Mat中的动态内存释放错误

Python acos() 函数

OpenCV 分配导致 std::thread::join 中的段错误

linux中的C++ OpenCV2 cv::Mat::copyTo错误