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

C++中修改cv::Mat内cv::Rect指定ROI区域并做线性变换

OpenCV局部ROI区域线性变换实现方案

OpenCV中cv::Mat用cv::Rect提取的ROI默认是原矩阵的浅拷贝,和原矩阵共享对应区域的内存,对ROI的修改会直接同步到原图像,不需要额外执行赋值回写操作。

具体实现代码

首先修正你代码里的参数类型问题:你的图像是CV_64FC1(双精度浮点单通道)类型,线性变换系数不能用int定义,否则int a=0.1会被截断为0,导致计算结果完全错误。

方法1:运算符重载直接实现(逻辑和你预期完全一致)

cv::Mat img = cv::Mat::zeros(msg->height, msg->width, CV_64FC1);
cv::Rect rect(100, 100, 20, 50);

// 先裁剪ROI到合法范围,避免越界崩溃
rect &= cv::Rect(0, 0, img.cols, img.rows);

double a = 0.1;
double b = 20;
// 提取ROI(浅拷贝,和原图共享内存)
cv::Mat roi = img(rect);
// 直接对ROI做线性变换,修改会自动同步到原图对应位置
roi = roi * a + b;

方法2:原生API原地运算(性能更优,无临时矩阵开销)

不需要额外定义ROI变量,直接在原矩阵对应区域原地执行线性变换:

cv::Mat img = cv::Mat::zeros(msg->height, msg->width, CV_64FC1);
cv::Rect rect(100, 100, 20, 50);
rect &= cv::Rect(0, 0, img.cols, img.rows);

double a = 0.1;
double b = 20;
// convertTo参数:目标矩阵,目标类型,缩放系数a,偏移量b,等价于*a +b
img(rect).convertTo(img(rect), CV_64FC1, a, b);

注意事项

  • 不要对提取的ROI调用.clone()或者.copyTo()生成深拷贝,否则修改ROI不会影响原图像,还需要额外执行拷贝操作才能回写结果,带来不必要的性能开销。
  • 运算前建议用rect &= cv::Rect(0, 0, img.cols, img.rows)裁剪ROI范围,避免ROI超出图像边界触发内存访问错误。
  • 所有参与运算的系数、变量类型要和矩阵的数据类型匹配,CV_64FC1对应double类型,CV_32FC1对应float类型,避免隐式类型转换导致的精度丢失或计算错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:42:43