当前位置: 首页 > news >正文

OpenCV图像裁剪与 ROI 操作

    在图像处理领域,ROI(Region of Interest)区域感兴趣操作是非常基础而重要的一环。无论是进行目标检测、图像分割,还是简单的图像处理,都离不开对图像某一区域的选取与处理。本文将结合 OpenCV 的 C++ 接口,详细介绍如何实现图像的裁剪与 ROI 操作。

    ROI(Region of Interest)表示“感兴趣区域”,是图像中你想要单独处理的一部分。例如,一张 1920×1080 的图像中,我们只想处理中间 300×300 的区域,这个区域就称为 ROI。在 OpenCV 中,ROI 通常通过设置图像的矩形区域来实现。

 

设置 ROI 区域并裁剪图像

// 定义一个矩形区域 ROI,位置(100, 100),大小(200×150)
cv::Rect roi(100, 100, 200, 150);// 使用 ROI 对图像进行裁剪
cv::Mat cropped = img(roi);cv::imshow("裁剪后的图像", cropped);

    以上代码实现了从大图像(img)中提取一个局部区域(ROI)图像cropped。

  • cv::Rect(x, y, width, height) 表示从 (x, y) 点开始,宽为 width,高为 height。
  • img(roi) 返回的是对原始图像的一块“视图”,不复制数据,我们称作为浅拷贝。

ROI 的复制与修改

因为 ROI 是视图,所以对其修改会影响原图。如果你不想修改原图,应当使用 .clone() 方法。

// clone 后成为一块新内存区域
cv::Mat roi_copy = cropped.clone();// 在 ROI 上画一个绿色矩形
cv::rectangle(cropped, cv::Point(0, 0), cv::Point(199, 149), cv::Scalar(0, 255, 0), 2);cv::imshow("在 ROI 上画矩形(影响原图)", img);
cv::imshow("ROI 拷贝(不受影响)", roi_copy);

以上代码中,clone函数返回新的内存数据区域,因此称作深拷贝。我们在cropped上绘制一个矩形区域,由于cropped是img的浅拷贝,img数据上同样也会绘制一个矩形。

 

用 ROI 做遮罩处理

// 创建一个遮罩
cv::Mat mask = cv::Mat::zeros(img.size(), CV_8UC1);
mask(roi).setTo(255);  // 设置 ROI 区域为白色// 提取 ROI 区域内容
cv::Mat result;
img.copyTo(result, mask);  // 使用遮罩复制内容cv::imshow("遮罩提取 ROI", result);

以上代码生成了一个mask遮罩,对于mask矩阵中的非零区域被视作有效区域,因此函数copyTo仅拷贝mask中非零区域所对应的img像素。

 

在 ROI 上应用图像处理(如模糊)

cv::Mat blurred;
cv::GaussianBlur(img(roi), blurred, cv::Size(15, 15), 0);// 将模糊图像复制回原图对应 ROI
blurred.copyTo(img(roi));cv::imshow("对 ROI 模糊处理后的图像", img);

在OpenCV中,很多函数可以传入一个ROI区域。因此我们在对图像局部区域进行操作时,可以不需要重新生成新的局部图像即可完成。但是注意一些特殊的函数可能不支持ROI区域操作,如cv::Mat::reshape(),cv::medianBlur()等。

 

完整代码

int main() {cv::Mat img = cv::imread("lena.png");if (img.empty()) {std::cerr << "无法读取图像!" << std::endl;return -1;}// 定义 ROI 区域,这是一个200*150的区域,左上角坐标为(100,100)// cropped定义了一个 ROI 矩阵,但和img使用相同的数据区域cv::Rect roi(100, 100, 200, 150);cv::Mat cropped = img(roi);cv::imwrite("1_cropped.png", cropped);// 在 ROI 上画框cv::rectangle(cropped, cv::Point(0, 0), cv::Point(199, 149), cv::Scalar(0, 255, 0), 2);cv::imwrite("2_rect.png", cropped);// ROI 的拷贝// 使用cv::Mat::clone函数进行深拷贝,roi_copy有单独的数据内存cv::Mat roi_copy = cropped.clone();cv::imwrite("3_roi_copy.png", roi_copy);// 遮罩提取// 生成一个mask遮罩,在roi区域内为255,其他区域为0cv::Mat mask = cv::Mat::zeros(img.size(), CV_8UC1);mask(roi).setTo(255);cv::imwrite("4_mask.png", mask);// 使用mask遮罩拷贝数据,此时仅将img图像中mask遮罩对应的数据拷贝到result中// 注意:copyTo也是深拷贝,并且该函数支持mask操作cv::Mat result;img.copyTo(result, mask);cv::imwrite("5_result.png", result);// 仅对 ROI 模糊处理// OpenCV中大多数函数支持基于ROI的操作,但有部分函数确不支持(需要特别留意)cv::Mat blurred;cv::blur(img(roi), blurred, cv::Size(15, 15));cv::imwrite("6_blurred.png", blurred);// 将模糊后图像拷贝到原图指定 ROI 上,copyTo支持 ROI 输入blurred.copyTo(img(roi));cv::imwrite("7_img.png", img);return 0;
}

对局部区域进行平滑操作

 

http://www.lryc.cn/news/615000.html

相关文章:

  • Kubernetes 集群密钥与机密管理方案对比分析:Vault、Sealed Secrets 与 AWS KMS
  • vue+flask山西非遗文化遗产图谱可视化系统
  • 【Linux】Tomcat
  • C# 异步编程(使用异步Lambda表达式)
  • 100-基于Python的智联招聘数据可视化分析推荐系统
  • 基于Dify实现对Excel的数据分析--动态配置图表
  • 篮球运动(动态规划)
  • Vue3子组件向父组件传值(defineEmits())
  • 年轻新标杆!东方心绣脸韧带年轻技术升级发布
  • 【线程池】压测确定线程池合适的参数
  • Qt/C++开发监控GB28181系统/实时监测设备在线离线/视频预览自动重连/重新点播取流/低延迟
  • 模板方法模式:优雅封装算法骨架
  • MX 播放器:安卓设备上的全能视频播放器
  • 浅谈 VM 桥接模式:让虚拟机像真实电脑一样接入网络
  • SimBA算法实现过程
  • day 36_2025-08-09
  • Gltf 模型 加载到 Cesium 的坐标轴映射浅谈
  • Mysql 分页查询优化
  • 使用lightGCN完整训练用户 + 商品向量的 3 步指南
  • jenkins-飞书通知机制
  • Windows系统NUL文件删除问题解决
  • 如何学习 react native 和 Expo
  • Spark02 - SparkContext介绍
  • Java基础-完成局域网内沟通软件的开发
  • 【和春笋一起学C++】(三十三)名称空间的其他特性
  • C++安全异常设计
  • 可泛化双手操作机器人基准测试:CVPR 2025 MEIS 研讨会 RoboTwin 双臂协作挑战赛
  • 【渲染流水线】[几何阶段]-[图元装配]以UnityURP为例
  • 第15届蓝桥杯Scratch选拔赛初级及中级(STEMA)2024年1月28日真题
  • Leetcode-19. 删除链表的倒数第 N 个结点