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

使用 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 提取是进行目标检测、图像分割和许多其他高级计算机视觉任务的基础。希望这篇文章能帮助你入门!

相关文章:

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

使用 C/C 和 OpenCV 提取图像的感兴趣区域 (ROI) 在计算机视觉中&#xff0c;感兴趣区域 (Region of Interest, ROI) 是指从图像中选择的一个特定区域&#xff0c;我们希望对其进行进一步的处理或分析。例如&#xff0c;在人脸识别中&#xff0c;ROI 就是包含人脸的矩形框。Op…...

TripGenie:畅游济南旅行规划助手:个人工作纪实(二十二)

这周&#xff0c;我进行了历史记录的设计与制作&#xff0c;我对于每一个用户与智能体交互得出的历史行程的数据进行了存储与可视化展示。 首先&#xff0c;我设置了一个csv文件存储每一个得出的行程规划&#xff0c;注意这里的地图我设置了一个全路径进行存储&#xff0c;这样…...

如何用AI高效运营1000+Tiktok矩阵账号

在当今数字化的时代&#xff0c;Tiktok 矩阵账号运营成为了众多企业和个人追求流量与变现的重要手段。然而&#xff0c;面对众多的账号管理&#xff0c;如何高效运营成为了关键。此时&#xff0c;AI 工具的出现为我们提供了强有力的支持。 一、Tiktok 矩阵账号的重要性 Tiktok…...

杭州瑞盟 MS35774/MS35774A 低噪声256细分微步进电机驱动,用于空调风门电机驱动,香薰电机驱动

杭州瑞盟 MS35774/MS35774A 低噪声256细分微步进电机驱动&#xff0c;用于空调风门电机驱动&#xff0c;香薰电机驱动 简述 MS35774/MS35774A 是一款高精度、低噪声的两相步进 电机驱动芯片&#xff0c;芯片内置功率 MOSFET &#xff0c;长时间工作的平均电 流可以达到 1…...

【论文解读】Toolformer: 语言模型自学使用工具

1st author: ‪Timo Schick‬ - ‪Google Scholar‬ paper: Toolformer: Language Models Can Teach Themselves to Use Tools | OpenReview NeurIPS 2023 oral code: lucidrains/toolformer-pytorch: Implementation of Toolformer, Language Models That Can Use Tools, by…...

408第一季 - 数据结构 - 线性表II

链表 头节点始终指向第一个 头节点的好处&#xff1a; 第一个好处 这里L是头节点 可以发现&#xff0c;删除第一个也可以统一了 第二个好处 这是无头节点&#xff0c;空和非空指向的不一样 然后有头节点就可以统一了&#xff01; 双链表 插入 第一步要在第四步之前&…...

网络通讯知识——通讯分层介绍,gRPC,RabbitMQ分层

网络通讯分层 网络通讯分层是为了将复杂的网络通信问题分解为多个独立、可管理的层次&#xff0c;每个层次专注于特定功能。目前主流的分层模型包括OSI七层模型和TCP/IP四层&#xff08;或五层&#xff09;模型&#xff0c;以下是详细解析&#xff1a; 一、OSI七层模型&#…...

Linux与Windows切换使用Obsidian,出现 unexplained changes 问题的解决

如果你的Obsidian文档在Linux与Windows间来回切换&#xff0c;可能会涉及到文件的保存换行符问题&#xff0c;但这样的话就容易导致一个问题&#xff0c;那就是内容无差异&#xff0c;Obsidian却提示unexplained changes&#xff0c;Windows系统下的解决方法如下&#xff0c;找…...

基于VMD-LSTM融合方法的F10.7指数预报

F10.7 Daily Forecast Using LSTM Combined With VMD Method ​​F10.7​​ solar radiation flux is a well-known parameter that is closely linked to ​​solar activity​​, serving as a key index for measuring the level of solar activity. In this study, the ​​…...

35 C 语言字符串转数值函数详解:strtof、strtod、strtold(含 errno 处理、ERANGE 错误)

1 strtof() 函数 1.1 函数原型 #include <stdlib.h> // 必须包含这个头文件才能使用 strtof() #include <errno.h> // 包含 errno 和 ERANGE #include <float.h> // 包含 FlOAT_MAX 和 FLOAT_MIN #include <math.h> // 包含 HUGE_VALF(inf)float…...

解决 idea提示`SQL dialect is not configured` 问题

前言 在 Java 开发中&#xff0c;尤其是使用 IntelliJ IDEA 或 MyBatis 等框架时&#xff0c;开发者常会遇到 SQL dialect is not configured 的警告或错误。这一问题不仅影响代码的高亮和智能提示功能&#xff0c;还可能导致表结构解析失败、语法校验失效等问题。 一、问题分…...

springboot的test模块使用Autowired注入失败

springboot的test模块使用Autowired注入失败的原因&#xff1a; 注入失败的原因可能是用了junit4的包的Test注解 import org.junit.Test;解决方法&#xff1a;再加上RunWith(SpringRunner.class)注解即可 或者把Test由junit4改成junit5的注解&#xff0c;就不用加上RunWith&…...

日志收集工具-Filebeat

提示&#xff1a;windows 环境下 Filebeat 的安装与使用 文章目录 前言一、安装二、配置部署三、启动测试 前言 Filebeat 一般用于日志采集&#xff0c;由两部分组成 &#xff1a;Harvesters 和 prospector Harvesters采集器&#xff1a;逐行读取单个文件的内容&#xff0c;并…...

【PCIe总线】 -- PCI、PCIe相关实现

PCI、PCIe相关概念和知识点 【PCIe总线】-- PCI、PCIe基础知识点整理 【PCIe】非常适合初学的pcie博客(PCIe知识整理) PCIe具体实现 【PCIe】如何获取PCIe的BAR空间大小&#xff1f;...

Vue3学习(4)- computed的使用

1. 简述与使用 作用&#xff1a;computed 用于基于响应式数据派生出新值&#xff0c;其值会自动缓存并在依赖变化时更新。 ​缓存机制​&#xff1a;依赖未变化时直接返回缓存值&#xff0c;避免重复计算&#xff08;通过 _dirty 标志位实现&#xff09;。​响应式更新​&…...

手机上网可以固定ip地址吗?详细解析

在移动互联网时代&#xff0c;手机已成为人们日常上网的主要设备之一。无论是工作、学习还是娱乐&#xff0c;稳定的网络连接都至关重要。许多用户对IP地址的概念有所了解&#xff0c;尤其是固定IP地址的需求。那么&#xff0c;手机上网能否固定IP地址&#xff1f;又该如何实现…...

电脑同时连接内网和外网的方法,附外网连接局域网的操作设置

对于工作一般都设置在内网网段中&#xff0c;而同时由于需求需要连接外网&#xff0c;一般只能通过内网和外网的不断切换进行设置&#xff0c;如果可以同时连接内网和外网会更加便利&#xff0c;同时连接内网和外网方法具体如下。 一、电脑怎么弄可以同时连接内网和外网&#…...

如何在Unity中实现点击一个按钮跳转到哔哩哔哩

1.创建一个按钮 2.编写一个脚本&#xff08;你可以把链接改成你想要跳转的网站&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class JumpToBilibili : MonoBehaviour {void Start(){gameObject.…...

DHCP 动态主机配置协议(Dynamic host configuration protocol)逐层封装过程: DHCP --> UDP --> IP

&#x1f4e6; DHCP 报文逐层封装结构&#xff08;自上而下&#xff09; 应用层&#xff08;DHCP 报文&#xff09; ↓ 传输层&#xff08;UDP 首部&#xff09; ↓ 网络层&#xff08;IP 首部&#xff09; ↓ 数据链路层&#xff08;以太网帧头&#xff09; ↓ 物理层&#x…...

PySide6 GUI 学习笔记——常用类及控件使用方法(单行文本控件QLineEdit)

文章目录 QLineEdit 介绍常用方法QLineEdit.EchoMode 取值光标相关方法文本选择方法输入格式化字符&#xff08;Input Mask&#xff09;常用信号QLineEdit 实例 QLineEdit 介绍 QLineEdit 是 PySide6&#xff08;Qt for Python&#xff09;中用于单行文本输入的控件。它支持文本…...

【数据结构】6. 时间与空间复杂度

文章目录 一、算法效率1、算法的复杂度 二、时间复杂度1、时间复杂度的概念2、大O的渐进表示法3、常见时间复杂度计算1&#xff09;实例12&#xff09;实例23&#xff09;实例34&#xff09;实例45&#xff09;实例56&#xff09;实例67&#xff09;实例78&#xff09;实例8 三…...

Python 函数全攻略:函数进阶(生成器、闭包、内置函数、装饰器、推导式)

一、默认参数中的易错点 问题: 当函数的默认参数是可变类型(如 list, dict)时,存在“坑”。 现象: def func(a2=[]): # a2 默认是一个空列表a2.append(2)print(a2)func() # 第一次调用,a2 默认为 [],输出 [2] func([]) # 传入新列表,输出 [2] func([1]) # 传入带元素的…...

基于springboot的藏文古籍系统

博主介绍&#xff1a;高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实实在…...

重构城市应急指挥布控策略 ——无人机智能视频监控的破局之道

在突发事件、高空巡查、边远区域布控中&#xff0c;传统摄像头常常“看不到、跟不上、调不动”。无人机智能视频监控系统&#xff0c;打破地面视角局限&#xff0c;以“高空布控 AI分析 实时响应”赋能政企单位智能化管理。在城市应急指挥中心的大屏上&#xff0c;一场暴雨正…...

声音信号的基频检测(python版本)

import math import wave import array import functools from abc import ABC, abstractmethod import matplotlib import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec import os import sys# 设计模式部分 class PreprocessStrategy(ABC):"&q…...

STM32 控制12VRGB灯带颜色亮度调节,TFTLCD显示

接了一个同学的小项目&#xff0c;要实现控制一个实体&#xff0c;控制灯带的亮度为红/绿/蓝/白/黄以及亮度的叠加。 时间要的比较急&#xff0c;要两天实现&#xff0c;因此不能打板&#xff0c;只能采用现有模块拼接。 一. 实施方案 一开始觉得很简单&#xff0c;就是使用五…...

Hive开窗函数的进阶SQL案例

​一、开窗函数基础​ 1. ​定义与作用​ 开窗函数&#xff08;Window Functions&#xff09;在保留原始行数据的同时&#xff0c;对分组内的行进行聚合或排序分析&#xff0c;常用于累计计算、排名、移动平均等场景。与普通聚合函数&#xff08;如SUM、AVG&#xff09;的区别…...

【JJ斗地主-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …...

《绩效管理》要点总结与分享

目录 绩效管理与目标设定 绩效管理的循环&#xff1a;PDCA 绩效目标的设定要点 绩效设定的工具&#xff1a;SMART法则 绩效跟踪与评估 刻板印象&#xff1a;STAR法 晕轮效应&#xff1a;对比评价法 近因效应&#xff1a;关键事项评估表 绩效面谈 面谈前准备工作 汉堡…...

Microsoft前后端不分离编程新风向:cshtml

文章目录 什么是CSHTML&#xff1f;基础语法内联表达式代码块控制结构 布局页面_ViewStart.cshtml_Layout.cshtml使用布局 模型绑定强类型视图模型集合 HTML辅助方法基本表单验证 局部视图创建局部视图使用局部视图 高级特性视图组件依赖注入Tag Helpers 性能优化缓存捆绑和压缩…...