坐标约定
跳转到“坐标约定”cv::Mat(rows, cols, type) 的参数是“行数、列数”;cv::Rect(x,y,width,height) 的参数是“左上角横坐标、纵坐标、宽、高”。图像左上角为原点,x 沿列增加,y 沿行增加。
区域对应半开范围:
因此有效区域应满足 、、、。image(rect) 产生共享原数据的子矩阵头,独立副本需要 clone()。Mat 区域与复制接口
带边界检查的例子
跳转到“带边界检查的例子”#include <opencv2/core.hpp>#include <iostream>
int main() { cv::Mat image(480, 640, CV_8UC3, cv::Scalar::all(0)); cv::Rect requested(100, 200, 100, 200); cv::Rect bounds(0, 0, image.cols, image.rows); if (requested.width <= 0 || requested.height <= 0 || (requested & bounds) != requested) { std::cerr << "ROI is outside the image\n"; return 1; }
cv::Mat roi = image(requested); cv::Mat independent = roi.clone(); roi.setTo(cv::Scalar(255, 0, 0)); std::cout << image.at<cv::Vec3b>(200, 100) << '\n'; std::cout << independent.at<cv::Vec3b>(0, 0) << '\n';}这会把原图中对应区域改为蓝色,而先前复制的 independent 保持黑色。若业务需要“超出边界时自动裁剪”,可取与 bounds 的交集,但必须明确这是改变区域尺寸的另一种策略,不能静默替代要求完整区域的逻辑。
38 × 8400 张量为什么不能直接用旧区域
跳转到“38 × 8400 张量为什么不能直接用旧区域”旧记录建立了 38 行、8400 列的矩阵,却使用 Rect(20,1000,17,400)。y=1000 已超过 38 行,区域无效。
如果确实要在未转置的矩阵中选取第 20 至 36 行、第 1000 至 1399 列,应写:
cv::Mat tensor(38, 8400, CV_32F, cv::Scalar(0));cv::Mat block = tensor(cv::Range(20, 37), cv::Range(1000, 1400));// 等价区域:cv::Rect(1000, 20, 400, 17)这里的数值只演示行列换算,不代表某个检测模型的输出定义。读取神经网络输出时,应先确认每一维的语义,再决定是否转置以及如何索引。
