You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV cv::Mat构造断言失败报错求助:原因与解决方案

OpenCV cv::Rect断言失败的原因与解决方法

错误原因

这个断言失败是因为你创建的cv::Rect(感兴趣区域ROI)超出了mFinalImage的图像边界,OpenCV要求ROI必须满足以下所有条件:

  • roi.x ≥ 0
  • roi.y ≥ 0
  • roi.width ≥ 0
  • roi.height ≥ 0
  • roi.x + roi.width ≤ mFinalImage.cols
  • roi.y + roi.height ≤ mFinalImage.rows

你的代码中,计算ROI的x、y坐标的公式存在逻辑问题,导致生成的Rect要么x/y为负数,要么Rect的右下角超出了mFinalImage的宽高范围。比如x坐标的计算式-final_vector[i - 1].x + minx + abs(minx),若minx为负数,代入后会简化为-final_vector[i-1].x,如果final_vector[i-1].x是较大的正数,就会导致roi.x + img.cols超过mFinalImage.cols;y坐标的计算逻辑也类似,容易出现负数或越界情况。

解决办法

1. 调试定位具体越界变量

在创建Rect前,打印所有关键变量的值,明确是哪个参数触发了断言:

for (size_t i = 1; i < count + 1; i++) {
    Mat img = vFrames[i - 1].Image1;
    int roi_x = -final_vector[i - 1].x + minx + abs(minx);
    int roi_y = -final_vector[i - 1].y - miny + abs(maxy);
    
    // 打印调试信息
    std::cout << "Iteration " << i << ":" << std::endl;
    std::cout << "roi_x: " << roi_x << ", roi_y: " << roi_y << std::endl;
    std::cout << "Image size: " << img.cols << "x" << img.rows << std::endl;
    std::cout << "mFinalImage size: " << mFinalImage.cols << "x" << mFinalImage.rows << std::endl;
    std::cout << "roi_x + cols: " << roi_x + img.cols << ", roi_y + rows: " << roi_y + img.rows << std::endl;

    Mat half1(mFinalImage, cv::Rect(roi_x, roi_y, img.cols, img.rows));
    img.copyTo(half1);
}

通过输出可以直接看到是x/y为负,还是宽高相加后超出了图像尺寸。

2. 修正坐标映射逻辑

从代码意图来看,你应该是想把final_vector中的坐标映射到mFinalImage的正区域内,正确的映射公式应该基于坐标的最小值做偏移:

  • x坐标:final_vector[i-1].x - minx(若minx是所有x的最小值,可保证x坐标≥0)
  • y坐标:final_vector[i-1].y - miny(同理,保证y坐标≥0)

替换后的代码示例:

int roi_x = final_vector[i - 1].x - minx;
int roi_y = final_vector[i - 1].y - miny;
Mat half1(mFinalImage, cv::Rect(roi_x, roi_y, img.cols, img.rows));
img.copyTo(half1);

3. 添加边界裁剪逻辑

即使修正了映射公式,也可能存在极端值导致Rect越界,因此可以手动裁剪ROI,确保它完全在mFinalImage范围内:

for (size_t i = 1; i < count + 1; i++) {
    Mat img = vFrames[i - 1].Image1;
    int roi_x = final_vector[i - 1].x - minx; // 修正后的x坐标
    int roi_y = final_vector[i - 1].y - miny; // 修正后的y坐标
    int roi_w = img.cols;
    int roi_h = img.rows;

    // 修正x方向边界
    roi_x = std::max(0, roi_x);
    roi_w = std::min(roi_w, mFinalImage.cols - roi_x);
    if (roi_w <= 0) continue; // 无有效区域,跳过

    // 修正y方向边界
    roi_y = std::max(0, roi_y);
    roi_h = std::min(roi_h, mFinalImage.rows - roi_y);
    if (roi_h <= 0) continue; // 无有效区域,跳过

    // 裁剪img对应的区域并复制
    Mat img_roi = img(cv::Rect(0, 0, roi_w, roi_h));
    Mat final_roi(mFinalImage, cv::Rect(roi_x, roi_y, roi_w, roi_h));
    img_roi.copyTo(final_roi);
}

内容的提问来源于stack exchange,提问作者omerkilicceker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 23:15:46