OpenCV 错误:断言失败,mat.cpp 第 537 行
Posted
技术标签:
【中文标题】OpenCV 错误:断言失败,mat.cpp 第 537 行【英文标题】:OpenCV Error: Assertion failed, mat.cpp line 537 【发布时间】:2013-11-26 12:24:40 【问题描述】:http://pastebin.com/5ZeMvm2C 是我项目中的头文件。
在第 249 行有skeleton.at(yaxis,xaxis+1)。当我在我的项目中键入此代码时,我收到了这个错误:
**OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)si
ze.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channel
s()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3
) - 1))*4) & 15) == elemSize1()) in unknown function, file c:\opencv\build\inclu
de\opencv2\core\mat.hpp, line 537**
// mat.cpp line 537 is:
template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
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 ((_Tp*)(data + step.p[0]*i0))[i1];
怎么了?
http://pastebin.com/gqJ5RpBU 也是我的 .cpp 文件。
【问题讨论】:
【参考方案1】:正如错误消息所说,您有一个失败的 OpenCV 运行时断言。
正如您在问题中所写,失败的断言位于 Mat::at
函数内。
您必须在您的代码中找到对Mat::at
的调用(或多个调用),这会给您带来错误。
正如您在OpenCV help page 中看到的,Mat::at
是一个带有一个、两个或三个参数的模板函数,断言失败可能有多种原因:
-
您使用了错误的模板参数(参见例如Using Mat::at(i,j) in opencv for a 2-D Mat object)
参数错误,例如在调用
template<typename T> T& Mat::at(int i, int j)
时,i
应该在0
和行数减一之间,j
应该在0
和列数减一。如果您有一个包含 100 行的图像并且您在第 101 行请求一个元素,则断言将失败。 Off-by-one errors 在这种情况下很常见。
更具体地说,断言失败是因为以下bool
s 中至少有一个是false
:
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())
上述bool
s 在Mat
类的范围内是有意义的。
此外,请注意帮助说明:
为了更高的性能,索引范围检查只 在 Debug 配置中执行
因此在您的发布配置中,您不会有失败的断言,但可能会在某处崩溃。
从你链接的源代码来看,在我看来你是在 Windows 上,如果这是真的并且如果你有 Visual Studio,我建议你从源代码构建 OpenCV,在 Mat::at
中放置一个断点和然后调试你的代码,看看之前的bool
s 是什么false
。
【讨论】:
对于其他读者:您可以在错误行上放置断点,当它命中时,使用 VS 中的 step into 按钮转到 mat.cpp 文件并查看data
, @987654346 的值@ , size.p[0] ,... 这样您就可以找到导致错误的值【参考方案2】:
Mat::at()
方法已经实现为模板,在使用该函数之前必须知道图片的类型。
检查图像的通道。 对于单通道图像(8UC1),您应该按如下方式操作图像像素:
image.at<uchar>(row, col) = 255;
对于三通道彩色图像(8UC3),你应该使用如下函数:
image.at<cv::Vec3b>(row, col)[channel] = 255;
如果通道没有问题,你应该检查at(i, j)
的参数,i表示行,j表示列。换句话说,i 等于 Point.y,j 等于 Point.x.
【讨论】:
以上是关于OpenCV 错误:断言失败,mat.cpp 第 537 行的主要内容,如果未能解决你的问题,请参考以下文章