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

使用 C/C++ 和 OpenCV 提取图像的感兴趣区域 (ROI)

使用 C/C++ 和 OpenCV 提取图像的感兴趣区域 (ROI)

在计算机视觉中,感兴趣区域 (Region of Interest, ROI) 是指从图像中选择的一个特定区域,我们希望对其进行进一步的处理或分析。例如,在人脸识别中,ROI 就是包含人脸的矩形框。OpenCV 提供了简单而高效的方法来提取 ROI。

本文将介绍如何使用 C++ 和 OpenCV 库来从图像中提取 ROI。

主要方法:使用 cv::Rect

最常用、最直接的方法是使用 cv::Rect 对象来定义 ROI。cv::Rect 指定了一个矩形区域,包含其左上角的坐标 (x, y) 以及矩形的宽度和高度。

核心步骤

  1. 加载图像:使用 cv::imread() 函数将图像读入一个 cv::Mat 对象。
  2. 定义矩形:创建一个 cv::Rect 对象,指定 ROI 的位置和尺寸。
  3. 提取 ROI:利用 cv::Mat 的括号 () 运算符,并传入 cv::Rect 对象来裁剪出 ROI。
  4. 显示结果:使用 cv::imshow() 分别显示原始图像和提取出的 ROI。

完整示例代码 👨‍💻

这是一个完整的 C++ 示例,它加载一张图片,从中提取一个指定的矩形区域,并同时显示原始图和 ROI 图。

#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 1. 读取原始图像// 确保图像文件 (例如 "sample_image.jpg") 在你的工作目录下,或提供完整路径cv::Mat originalImage = cv::imread("sample_image.jpg");if (originalImage.empty()) {std::cerr << "Error: Could not load the image!" << std::endl;return -1;}// 2. 定义 ROI 的矩形区域// cv::Rect(x, y, width, height)// - x: ROI 左上角的 x 坐标// - y: ROI 左上角的 y 坐标// - width: ROI 的宽度// - height: ROI 的高度//// 假设我们想从坐标 (250, 100) 开始,提取一个 300x400 大小的区域int x = 250;int y = 100;int width = 300;int height = 400;// 安全检查:确保定义的 ROI 没有超出原始图像的边界if ((x + width > originalImage.cols) || (y + height > originalImage.rows)) {std::cerr << "Error: The defined ROI exceeds the image boundaries!" << std::endl;return -1;}cv::Rect roiRect(x, y, width, height);// 3. 提取 ROI// 使用矩形对象来索引原始图像,创建一个指向 ROI 的 Mat 头cv::Mat roiImage = originalImage(roiRect);// 4. 显示结果cv::imshow("Original Image", originalImage);cv::imshow("ROI Image", roiImage);// 等待用户按键后退出cv::waitKey(0);cv::destroyAllWindows();return 0;
}

如何编译和运行 (使用 CMake)

使用 CMake 是管理 C++ 和 OpenCV 项目的标准方式。

  1. 将以上代码保存为 extract_roi.cpp
  2. 在同一目录下创建 CMakeLists.txt 文件:
    cmake_minimum_required(VERSION 3.10)
    project(ExtractROI_Project)find_package(OpenCV REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS})add_executable(extract_roi extract_roi.cpp)
    target_link_libraries(extract_roi ${OpenCV_LIBS})
    
  3. 准备一张图片,并将其命名为 sample_image.jpg(或修改代码中的文件名)。
  4. 在终端中执行以下命令进行编译和运行:
    mkdir build
    cd build
    cmake ..
    make
    ./extract_roi
    

运行后,你将看到两个窗口,一个显示原始全图,另一个仅显示你提取的感兴趣区域。


重要提示:视图 vs. 拷贝 ⚠️

默认情况下,通过 image(roiRect) 操作创建的 cv::Mat 不是一个独立的数据拷贝,而是一个指向原始图像内存的视图 (View) 或称“头 (Header)”。

这意味着:

  • 内存共享roiImageoriginalImage 共享同一块图像数据。
  • 双向影响:如果你在 roiImage 上绘制或进行修改,这些改动会直接反映在 originalImage 的对应区域

如何创建独立拷贝?

如果你希望对 ROI 进行修改而不影响原始图像,你需要创建一个数据的深拷贝 (Deep Copy)。这可以通过 clone()copyTo() 方法实现。

// 方法 1: 使用 clone()
cv::Mat roi_clone = originalImage(roiRect).clone();// 方法 2: 使用 copyTo()
cv::Mat roi_copy;
originalImage(roiRect).copyTo(roi_copy);

现在,对 roi_cloneroi_copy 的任何修改都将是独立的,不会影响 originalImage


掌握 ROI 提取是进行目标检测、图像分割和许多其他高级计算机视觉任务的基础。希望这篇文章能帮助你入门!

http://www.lqws.cn/news/202591.html

相关文章:

  • Mysql批处理写入数据库
  • Opencv查找图形形状的重要API讲解
  • Cursor实现用excel数据填充word模版的方法
  • C#报价系统陈列展示成本核算系统项目管理系统纸品非纸品报价软件
  • linux 用户态时间性能优化工具perf/strace/gdb/varlind/gprof
  • 让DeepSeek写2025年高考作文
  • qiankun微前端 主应用vue3+vite、子应用vue3+vite
  • 使用 C++/OpenCV 创建动态流星雨特效 (实时动画)
  • ngx_stream_geo_module在传输层实现高性能 IP Region 路由
  • 学习STC51单片机30(芯片为STC89C52RCRC)
  • 【论文阅读笔记】《A survey on deep learning approaches for text-to-SQL》
  • 以SMMUv2为例,使用Trace32可视化操作SMMU的常用命令详解
  • 深入理解 Agent 与 LLM 的区别:从智能体到语言模型
  • 反向传播的核心是什么:计算损失函数对可训练参数的梯度=== 损失函数能通过计算图连接到可训练参数
  • 快速运行Dify前端,无需搭建后端环境
  • CADisplayLink、NSTimer、GCD定时器
  • 变幻莫测:CoreData 中 Transformable 类型面面俱到(一)
  • opencv_stereoRectify源码解析
  • 客户端和服务器已成功建立 TCP 连接【输出解析】
  • Clahs——问题解决:软件所有节点均超时
  • 能上Nature封面的idea!强化学习+卡尔曼滤波
  • C++之STL--list
  • 智能客服路由实战之RunnableBranch条件分支
  • 复旦联合百度发布Hallo4:让AI肖像“活”起来!新型扩散框架实现高保真音频驱动动画生成!
  • Python 函数全攻略:函数进阶(生成器、闭包、内置函数、装饰器、推导式)
  • AI大模型:(二)3.2 Llama-Factory微调训练deepseek-r1实践
  • 微前端架构下的B端页面设计:模块化与跨团队协作的终极方案
  • 【图像处理基石】如何构建一个简单好用的美颜算法?
  • 向 AI Search 迈进,腾讯云 ES 自研 v-pack 向量增强插件揭秘
  • JAVA理论第五章-JVM