码迷,mamicode.com
首页 > 其他好文 > 详细

opencv-2.4.9的bug?

时间:2014-12-03 23:13:31      阅读:1848      评论:0      收藏:0      [点我收藏+]

标签:style   io   ar   color   os   sp   for   strong   on   

这几天在调试一个opencv的demo程序,总是crash,诊断信息为

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file U:\OpenCv\opencv-2.4.9\sources\modules\core\include\opencv2/core/mat.hpp, line 545

call stack为

opencv_core249d.dll!cv::error(const cv::Exception & exc={...})  Line 546    C++
opencv_calib3d249d.dll!cv::Mat::at<cv::Point3_<float> >(int i0=0, int i1=1)  Line 543 + 0xf6 bytes    C++
opencv_calib3d249d.dll!epnp::init_points<cv::Point3_<float>,cv::Point_<float> >(const cv::Mat & opoints={...}, const cv::Mat & ipoints={...})  Line 29 + 0xe bytes    C++
opencv_calib3d249d.dll!epnp::epnp(const cv::Mat & cameraMatrix={...}, const cv::Mat & opoints={...}, const cv::Mat & ipoints={...})  Line 22    C++
opencv_calib3d249d.dll!cv::solvePnP(const cv::_InputArray & _opoints={...}, const cv::_InputArray & _ipoints={...}, const cv::_InputArray & _cameraMatrix={...}, const cv::_InputArray & _distCoeffs={...}, const cv::_OutputArray & _rvec={...}, const cv::_OutputArray & _tvec={...}, bool useExtrinsicGuess=false, int flags=1)  Line 64 + 0x1d bytes    C++
SHPE.exe!loadWithPoints(cv::Mat & ip={...}, cv::Mat & img={...})  Line 326 + 0xc4 bytes    C++
SHPE.exe!loadNext()  Line 311 + 0x13 bytes    C++
SHPE.exe!main(int argc=1, char * * argv=0x0261e310)  Line 408    C++

在网上搜了一下,也没找到什么有价值的线索。于是决定自己花点功夫调试一下,看看究竟是什么问题。

从cv::error往上一层,进入Mat::at函数

template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
{
    CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
        (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
    return ((const _Tp*)(data + step.p[0]*i0))[i1];
}

查看一下this的内容

this    0x003be898 {flags=1124024341 dims=2 rows=7 ...}    const cv::Mat * const
        flags    1124024341    int
        dims    2    int
        rows    7    int
        cols    1    int

this是一个7x1的二维矩阵,元素类型为Point3f; 调用了at函数取坐标为(0,1)的元素。这就有问题了,7x1的二维矩阵不存在(0,1)这个坐标呀,出现assertion会不会是这个原因呢。

再仔细检测 CV_DbgAssert的几个判断条件,发现问题出在这里: (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels())

这个判断的意思是:列坐标 * 元素的通道数 < 矩阵列数 * 矩阵通道数;由于元素通道数(DataType<Point3f>::channels)和矩阵通道数(channels())都为3;再化简一下就是:列坐标 < 矩阵列数。

这样一来就明白了这个判断是对列坐标做边界检测;由于列坐标1超出了边界,所以出现了assertion错误。

再往上进入上一级函数epnp::init_points:

template <typename OpointType, typename IpointType>
  void init_points(const cv::Mat& opoints, const cv::Mat& ipoints)
  {
      for(int i = 0; i < number_of_correspondences; i++)
      {
          pws[3 * i    ] = opoints.at<OpointType>(0,i).x;
          pws[3 * i + 1] = opoints.at<OpointType>(0,i).y;
          pws[3 * i + 2] = opoints.at<OpointType>(0,i).z;

          us[2 * i    ] = ipoints.at<IpointType>(0,i).x*fu + uc;
          us[2 * i + 1] = ipoints.at<IpointType>(0,i).y*fv + vc;
      }
  }

从这段代码来看,似乎是要无视矩阵的行/列结构,强制将矩阵当成一个一维数组来访问;却在at函数中由于边界检查识别而抛出了诊断错误。

为了印证这一点,我又查看了opencv-3.0-beta中epnp::init_points的代码,发现已经被改成:

template <typename OpointType, typename IpointType>
  void init_points(const cv::Mat& opoints, const cv::Mat& ipoints)
  {
      for(int i = 0; i < number_of_correspondences; i++)
      {
          pws[3 * i    ] = opoints.at<OpointType>(i).x;
          pws[3 * i + 1] = opoints.at<OpointType>(i).y;
          pws[3 * i + 2] = opoints.at<OpointType>(i).z;

          us[2 * i    ] = ipoints.at<IpointType>(i).x*fu + uc;
          us[2 * i + 1] = ipoints.at<IpointType>(i).y*fv + vc;
      }
  }

真是不敢相信在正式的release版本中会存在这么明显的bug。如果不是bug,那为什么demo从2.4.9换到3.0就好了。

opencv-2.4.9的bug?

标签:style   io   ar   color   os   sp   for   strong   on   

原文地址:http://www.cnblogs.com/panruochen/p/4141442.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!