[具身智能-236]:OpenCV ROI:Region of Interest(感兴趣区域)
·
在 OpenCV 中,ROI 是 Region of Interest(感兴趣区域)的缩写。
简单来说,ROI 就是从图像中切出来的“一块”。在处理图像时,我们往往不需要处理整张图片(比如处理人脸时不需要管背景里的树),通过提取 ROI,我们可以只关注重点区域,从而大幅提升处理速度和算法精度。
结合最新的 OpenCV 开发实践,我为你整理了 ROI 的核心操作指南:
📐 基础操作:矩形 ROI
这是最常用、最高效的方式。在 Python 中,OpenCV 图像本质上是 NumPy 数组,因此我们直接使用数组切片来提取 ROI。
关键口诀:先行后列,即 [y, x] 或 [高, 宽]。
python
import cv2
# 1. 读取图像
img = cv2.imread('example.jpg')
# 2. 提取 ROI
# 语法:img[y1:y2, x1:x2]
# 含义:从第 y1 行到 y2 行,从第 x1 列到 x2 列
roi = img[100:300, 200:400] # 提取坐标 (200,100) 到 (400,300) 的矩形区域
# 3. 显示 ROI
cv2.imshow('ROI', roi)
cv2.waitKey(0)
常见应用场景:
- 复制粘贴:将 ROI 复制到图像的其他位置(如
img[500:700, 200:400] = roi)。 - 局部处理:只对 ROI 进行模糊、边缘检测等操作,节省计算资源。
🎭 进阶操作:不规则 ROI (圆形、多边形)
如果你想提取圆形、椭圆或任意多边形区域,简单的切片就不够用了。这时需要用到 Mask(掩膜) 技术。
核心逻辑: 创建一个与原图同尺寸的“黑白图”(Mask),白色代表保留,黑色代表舍弃,然后通过按位与运算提取。
python
import cv2
import numpy as np
img = cv2.imread('example.jpg')
h, w = img.shape[:2]
# --- 场景 A:圆形 ROI ---
# 1. 创建全黑 Mask
mask = np.zeros((h, w), dtype=np.uint8)
# 2. 在 Mask 上画一个白色的圆
cv2.circle(mask, (w//2, h//2), 100, (255), -1) # 圆心在中间,半径100
# 3. 提取 ROI
circular_roi = cv2.bitwise_and(img, img, mask=mask)
# --- 场景 B:多边形 ROI (任意形状) ---
# 1. 创建全黑 Mask
mask_poly = np.zeros((h, w), dtype=np.uint8)
# 2. 定义多边形顶点
pts = np.array([[100,100], [200,100], [200,200], [100,250]], np.int32)
pts = pts.reshape((-1, 1, 2))
# 3. 填充白色多边形
cv2.fillPoly(mask_poly, [pts], (255))
# 4. 提取 ROI
poly_roi = cv2.bitwise_and(img, img, mask=mask_poly)
cv2.imshow('Circular ROI', circular_roi)
cv2.imshow('Polygon ROI', poly_roi)
cv2.waitKey(0)
🖱️ 交互式选择 ROI
如果你在写调试工具,不想每次都手动去量坐标,可以使用 OpenCV 自带的交互函数。
cv2.selectROI:弹出一个窗口,让你用鼠标框选区域,返回(x, y, w, h)。
python
img = cv2.imread('example.jpg')
# 按下空格键确认选择,按 ESC 取消
x, y, w, h = cv2.selectROI("Select ROI", img, False)
# 根据返回值裁剪
roi = img[y:y+h, x:x+w]
cv2.imshow("Selected ROI", roi)
cv2.waitKey(0)
⚡ 为什么要用 ROI?(性能对比)
使用 ROI 不仅仅是为了裁剪图片,更是为了性能优化。在视频处理或高分辨率图像分析中,差异巨大。
假设我们要对一张 1920×1080 的图片做高斯模糊:
表格
| 处理方式 | 处理区域大小 | 耗时 (估算) | 说明 |
|---|---|---|---|
| 全图处理 | 1920 × 1080 | ~450ms | 计算量大,浪费资源处理背景 |
| ROI 处理 | 200 × 200 | ~30ms | 速度提升 90% 以上,只算核心区域 |
💡 避坑指南
- 坐标顺序:再次强调,NumPy 切片是
img[y:y+h, x:x+w],也就是img[行范围, 列范围]。很多初学者写成img[x, y]会导致报错或截取到错误的长条区域。 - 越界问题:切片的坐标不能超出图像的实际宽高,否则会报错
IndexError。 - 引用与拷贝:
roi = img[0:100, 0:100]得到的是视图(引用),修改roi会直接改变原图img。- 如果你希望修改 ROI 而不影响原图,必须使用
.copy(),例如roi = img[0:100, 0:100].copy()。
掌握 ROI 是 OpenCV 入门的第一步,也是从“处理整图”进阶到“精准视觉分析”的关键。
更多推荐

所有评论(0)