opencv-2.4.9的bug?

这几天在调试一个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就好了。

时间: 2025-01-04 14:17:39

opencv-2.4.9的bug?的相关文章

用opencv读取图像鼠标点的像素,更正一个Bug

作者:skyseraph 出处:http://www.cnblogs.com/skyseraph/ 以下代码在网上流传很广. 不过,调试运行之后发现,功能是正确的,但是内存很快就耗尽,导致死机.经过查找,加上: cvReleaseImage(&img1);    //释放源图像占用的内存 这一行是我(szliug)加的,否则内存很快就会耗尽,会死机的. 之后运行正常. /*===============================================// 功能:OpenCV Ut

opencv vs工程复制到另外一个文件夹出现bug的解决方法

当我一个工程从C盘拷到E盘后,然后再打开却出现下面这种情况: 出现这种情况,首先右键Reload一下,然后出现下面这个错误 发现显示是在vcxproj文件中没有找到opencv的props文件,于是便打开这个vcxproj文件便发现下面 其中 这句<Import Project="..\..\..\..\..\..\opencv249\Opencv2Debug.props" />表明对应的opencv配置的props文件必须得在当前工程的路径下, 但是我把props的默认文

Kinect2入门+opencv画骨架+骨架数据

////////////////////////////准备工作/////////////////////////////// 首先需要下载安装Kinect2的SDK,下载地址如下: https://www.microsoft.com/en-us/download/details.aspx?id=44561 建议安装时从官网下载,之前有出现过拷贝的文件无法正常安装的情况. //注意V2.0以下版本为一代Kinect所用,一代Kinect推荐V1.8 相对于一代的Kinect,二代由于SDK只出过

【OpenCV入门教程之一】 OpenCV 2.4.8 +VS2010的开发环境配置

目录(?)[-] 因为读研期间的研究方向是图像处理所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容眼看自己积累到一定的程度了于是决定开始开设这个OpenCV系列专栏总结自己所学也分享知识给大家 还是先放出待会儿的测试用图 下载和安装OpenCV SDK sources里面是源代码想查看完整的源代码需要用cmake来解包如何解包大家百度一下就可以或者下次浅墨来专门讲一讲这里就先不多说了 配置环境变量 工程包含include目录的配置 工程库lib目录的配置 链接库的配置 在Wi

opencv 学习方法

1. 学习方法: http://www.opencv.org.cn/forum.php?mod=viewthread&tid=7055&extra=&page=1 首先还是说说如何学Opencv吧,记得最开始进实验室的时候师兄让看Opencv,当时的学术基础很差,编程能力也很一般,所以学Opencv时感到很无助,像是陷入了一个死循环.想通过算法看代码,发现算法不会:通过代码学算法,又发现自己读代码的能力很弱.后来通过不断的读文章(下面会推荐几篇文章供算法入门)和加强实际的编程能力,

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的.对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug. sorry,废话多了.首先给个思路: 1.使opencv 的hi

OPENCV(环境配置)

转:http://blog.csdn.net/poem_qianmo/article/details/19809337 其中:跳过了"2.配置环境变量",其它大致一样. 最后出现几个错误,分别是: 第一个错误:fatal error LNK1104: 无法打开文件".obj":LINK : fatal error LNK1104: 无法打开文件"xx.lib" 解决方案:http://blog.sina.com.cn/s/blog_9015f32

使用OpenCL+OpenCV实现图像旋转(一)

[题外话]近期申请了一个微信公众号:平凡程式人生.有兴趣的朋友可以关注,那里将会涉及更多更新OpenCL+OpenCV以及图像处理方面的文章. 最近在学习<OPENCL异构计算>,其中有一个实例是使用OpenCL实现图像旋转.这个实例中并没有涉及读取.保存.显示图像等操作,其中也存在一些小bug.在学习OpenCL之初,完整地实现这个实例还是很有意义的事情. 1.图像旋转原理 所谓图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程.这个点通常就是图像的中心. 由于是按照中心旋

MFC+opencv+高斯背景前景提取图像显示问题

最近做项目遇到一个问题,再用混合高斯背景模型提取前景图显示到MFC窗口上的时候,出现了一个问题,图像显示不正常.显示效果如下图: 我是使用Mat类型图像和imshow进行显示的,出现这个状况出乎意料.因为其他都能正常显示. 之后开始在网上查找问题所在,可是经过多方查找,发现网上根本没有此类问题.尴尬. 最后无奈开始各方求助,问答啊,论坛帖子啊都试过却没人解答...最后幸好通过指导老师认识了一个研三学长,学长说由于opencv与MFC图像格式不一样所以才会出现这个问题,需要将Mat导成二进制流再转