学习OpenCV3:Assertion failed错误


1、背景

  最近编写如下代码,运行时窗口一闪而过,最后终端报出错误Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == _sz) in create

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main()
{
    const std::string name = "image";
    cv::namedWindow(name, cv::WINDOW_AUTOSIZE);
    int w = 100, h = 300, y = 50;

    // 黑图白线
    cv::Mat img1(w, h, CV_8UC1, cv::Scalar(0)); // cv::Mat img = cv::Mat::zeros(w, h, CV_8UC1);
    cv::line(img1, cv::Point(0, y), cv::Point(img1.cols, y), cv::Scalar(255), 2);

    // 白图黑线
    cv::Mat img2(w, h, CV_8UC1, cv::Scalar(255)); // cv::Mat img = cv::Mat::ones(w, h, CV_8UC1) * 255;
    cv::line(img2, cv::Point(0, y), cv::Point(img2.cols, y), cv::Scalar(0), 2);

    // 蓝图绿线
    cv::Mat img3(w, h, CV_8UC3, cv::Scalar(255, 0, 0));
    cv::line(img3, cv::Point(0, y), cv::Point(img3.cols, y), cv::Scalar(0, 255, 0), 2);

    // 三张图片合并到一张图片上显示
    cv::Mat img(3 * w, h, CV_8UC3);
    cv::cvtColor(img1, img(cv::Rect(0, 0, w, h)), cv::COLOR_GRAY2BGR);
    cv::cvtColor(img2, img(cv::Rect(w, 0, w, h)), cv::COLOR_GRAY2BGR);
    img3.copyTo(img(cv::Rect(2 * w, 0, w, h)));

    cv::imshow(name, img);
    cv::waitKey();
    return 0;
}

终端错误提示:

OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(3.4.10) Error: Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == _sz) in create, file D:\opencv3410\sources\modules\core\src\matrix_wrap.cpp, line 1194

类似的错误:

OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(3.4.10) Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows) in Mat, file D:\opencv3410\sources\modules\core\src\matrix.cpp, line 466

2、分析

  首先,由错误提示中的Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == _sz) in create,以及调试时报错的代码推断错误原因是:cv::Rect表示的范围与图片img1的尺寸不相符

    cv::cvtColor(img1, img(cv::Rect(0, 0, w, h)), cv::COLOR_GRAY2BGR);
    cv::cvtColor(img2, img(cv::Rect(w, 0, w, h)), cv::COLOR_GRAY2BGR);
    img3.copyTo(img(cv::Rect(2 * w, 0, w, h)));

  然后,分别显示图片img1img(cv::Rect(0, 0, w, h)),可发现两张图片宽高正好相反。

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main()
{
    const std::string name = "image";
    cv::namedWindow(name, cv::WINDOW_AUTOSIZE);
    int w = 100, h = 300, y = 50;

    // 黑图白线
    cv::Mat img1(w, h, CV_8UC1, cv::Scalar(0)); // cv::Mat img = cv::Mat::zeros(w, h, CV_8UC1);
    cv::line(img1, cv::Point(0, y), cv::Point(img1.cols, y), cv::Scalar(255), 2);

    // 白图黑线
    cv::Mat img2(w, h, CV_8UC1, cv::Scalar(255)); // cv::Mat img = cv::Mat::ones(w, h, CV_8UC1) * 255;
    cv::line(img2, cv::Point(0, y), cv::Point(img2.cols, y), cv::Scalar(0), 2);

    // 蓝图绿线
    cv::Mat img3(w, h, CV_8UC3, cv::Scalar(255, 0, 0));
    cv::line(img3, cv::Point(0, y), cv::Point(img3.cols, y), cv::Scalar(0, 255, 0), 2);

    // 三张图片合并到一张图片上显示
    cv::Mat img(3 * w, h, CV_8UC3);
    cv::imshow("1", img1);
    cv::imshow("2", img(cv::Rect(0, 0, w, h)));
    // cv::cvtColor(img1, img(cv::Rect(0, 0, w, h)), cv::COLOR_GRAY2BGR);
    // cv::cvtColor(img2, img(cv::Rect(w, 0, w, h)), cv::COLOR_GRAY2BGR);
    // img3.copyTo(img(cv::Rect(2 * w, 0, w, h)));

    // cv::imshow(name, img);
    cv::waitKey();
    return 0;
}

  最后,检查前面的代码发现错误原因是:定义和初始化图片错误,wh使用颠倒

// 构造函数,rows对应h,cols对应w
cv::Mat(int rows, int cols, int type, const Scalar&s)
// 错误代码
cv::Mat img1(w, h, CV_8UC1, cv::Scalar(0));

3、修改

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

int main()
{
    const std::string name = "image";
    cv::namedWindow(name, cv::WINDOW_AUTOSIZE);
    int w = 300, h = 100, y = 50;

    // 黑图白线
    cv::Mat img1(h, w, CV_8UC1, cv::Scalar(0)); // cv::Mat img = cv::Mat::zeros(w, h, CV_8UC1);
    cv::line(img1, cv::Point(0, y), cv::Point(img1.cols, y), cv::Scalar(255), 2);

    // 白图黑线
    cv::Mat img2(h, w, CV_8UC1, cv::Scalar(255)); // cv::Mat img = cv::Mat::ones(w, h, CV_8UC1) * 255;
    cv::line(img2, cv::Point(0, y), cv::Point(img2.cols, y), cv::Scalar(0), 2);

    // 蓝图绿线
    cv::Mat img3(h, w, CV_8UC3, cv::Scalar(255, 0, 0));
    cv::line(img3, cv::Point(0, y), cv::Point(img3.cols, y), cv::Scalar(0, 255, 0), 2);

    // 三张图片合并到一张图片上显示
    cv::Mat img(3 * h, w, CV_8UC3);
    cv::cvtColor(img1, img(cv::Rect(0, 0, w, h)), cv::COLOR_GRAY2BGR);
    cv::cvtColor(img2, img(cv::Rect(0, h, w, h)), cv::COLOR_GRAY2BGR);
    img3.copyTo(img(cv::Rect(0, 2 * h, w, h)));

    cv::imshow(name, img);
    cv::waitKey();
    return 0;
}

4、总结

1、OpenCV出现Assertion failed之类的错误,一般都是如数组、矩阵、ROI等数据超出实际有效范围。
2、OpenCV中cols表示列数,对应xw等横坐标;rows表示行数,对应yh等纵坐标。使用时需特别注意参数中colsrows的先后顺序。

### 回答1: "OpenCV 错误:断言失败"意味着在使用 OpenCV 的过程中,程序发现了一个不符合预期的状态或条件。这可能是由于程序代码中的错误OpenCV 库中的错误导致的。建议检查程序代码并确保所有参数和条件都是正确的,同时确保使用的 OpenCV 版本是最新版本。 ### 回答2: 在使用OpenCV进行编程时,有时会遇到 "opencv error: assertion failed" 的错误。这通常是因为代码中有一个断言(assertion)没有通过而导致的。断言是一种用于调试的手段,它可以检查程序中的一些假设是否成立。如果断言失败,程序会终止并输出错误信息,以帮助找出问题。 在OpenCV中,常见的断言包括检查图像矩阵的大小是否符合要求、数组索引是否越界、指针是否为空等等。当这些条件不成立时,就会出现 "opencv error: assertion failed" 的错误。 解决这个错误的方法通常是查看程序中的相关代码,找出断言失败的原因并进行修复。一些常见的解决方法如下: 1. 检查图像矩阵的大小是否符合要求。例如,如果图像矩阵的大小与代码的预期大小不一致,就可能会导致断言失败。可以通过检查图像或矩阵的行数、列数、通道数等来解决这个问题。 2. 检查数组索引是否越界。如果访问了数组的无效索引,就可能会出现断言失败。可以通过检查索引的范围来解决这个问题。 3. 检查指针是否为空。如果操作了空指针,就可能会出现断言失败。可以通过检查指针是否为空来解决这个问题。 4. 检查函数参数是否正确。如果函数的参数不正确,就可能会出现断言失败。可以通过检查函数的使用方式来解决这个问题。 总之,如果遇到 "opencv error: assertion failed" 的错误,需要仔细检查程序中的相关代码,并找出断言失败的原因。通过保证图像矩阵的大小、数组索引、指针以及函数参数等的正确性,可以避免这个错误的发生。 ### 回答3: OpenCV是一款广泛使用的开源计算机视觉库,经常被用于图像处理和计算机视觉的开发。在开发过程中,有时会出现"opencv error: assertion failed"的错误提示信息。 该错误意味着代码中的某个断言失败了,即某个条件没有满足。在OpenCV中,这些断言通常使用"CV_Assert"进行检测。当这个条件不满足时,系统会停止运行并提示"opencv error: assertion failed"的错误信息。 造成这个错误的原因有很多,常见的几种情况如下: 1. 内存不足。这种情况下,程序需要更多的内存才能继续处理。可通过减少程序内存使用或增加计算机内存来解决这个问题。 2. 数据类型不匹配。代码中使用的数据类型与实际数据类型不一致,比如输入图像类型与代码中要求的图像类型不一致。需要检查代码中的数据类型与实际数据类型是否匹配。 3. 数组越界。代码尝试访问数组的未分配内存,或者访问越界。需要检查代码中数组访问的范围是否正确。 4. 函数参数错误。某些OpenCV函数有特定的输入参数要求,如果这些参数不正确,就会发生断言失败的错误。需要检查函数的输入参数是否正确。 解决这个错误的方法有很多种,具体方法取决于具体原因。可以通过调试程序、检查输入参数、检查代码逻辑等方法解决问题。如果还无法解决问题,可以在OpenCV官方社区或其他开发者社区中寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值