机器视觉学习-day05-ROI切割
1 ROI切割
ROI(Region of Interest,感兴趣区域)指的是从原始图像中定义出特定的区域,该区域对于后续的分析、处理具有特别的意义。
比如对于一个人的照片,加入算法要检测眼睛,因为眼睛肯定在脸上,所以只要对脸部感兴趣,其他区域无视,可以通过ROI切割把人脸截取出来,这样的节省计算量,提高程序的运行速度。
ROI切割本质上是通过Numpy数组的切片操作完成。
代码步骤:图片输入→图片切割→图片输出
代码参数:
x_min:ROI区域最小的横坐标
x_max:ROI区域最大的横坐标
y_min:ROI区域最小的纵坐标
y_max:ROI区域最大的纵坐标
在OpenCV中坐标的x轴正方向是水平向右的,y轴的正方向是垂直向下的。
另外Numpy存储图像是一个三维数组:
第一个维度(0):高度(行数)
第二个维度(1):宽度(列数)
第三个维度(2) :三个通道BGR的像素值
实际处理中需要注意x(列数)和y(行数)的顺序。
练习:在 1.jpg 的图片中,想要截取小狗的头部。
import cv2
from matplotlib import pyplot as pltcv2.namedWindow('image_np', cv2.WINDOW_NORMAL)
cv2.resizeWindow('image_np', 800, 500)if __name__ == '__main__':# 1. 图片输入path = '1.jpg'# 因为ROI区域可能越界,可以加入异常处理机制try:image_np = cv2.imread(path) # 读取图片到numpy数组(三维数组:高度、宽度、通道BGR)# 获得图像尺寸(h, w, _) = image_np.shape# h=高度, w=宽度, _=通道数(不需要用所以用下划线)print(h, w)# 2. 图片切割(定义ROI区域)x_min, x_max = 300, 603 # 水平方向起点/终点(列坐标)y_min, y_max = 354, 670 # 垂直方向起点/终点(行坐标)# 边界检查:确保ROI在图像范围内if not ((x_min > 0) and (x_max < w) and (y_min > 0) and (y_max < h)):raise OverflowError('范围越界!!!') # 手动抛出越界异常if (x_min >= x_max) or (y_min >= y_max):raise ValueError("最值错误!!!") # 起点不能>=终点# 矩形框线宽line_width = 2# 创建图像副本(避免修改原图)# image_np_copy = image_np.copy() # (方法2,下面x,y不需要拓宽)# 在原图上绘制红色矩形标记ROI区域cv2.rectangle(image_np, # 目标图像(x_min - 2, y_min - 2), # 矩形左上角坐标(x_max + 2, y_max + 2), # 矩形右下角坐标(0, 0, 255), # BGR颜色(红色)line_width # 线宽)# 切片提取ROI区域(注意:图像数组是[y, x]顺序)# y_min:y_max → 行范围, x_min:x_max → 列范围ROI_imge = image_np[y_min:y_max, x_min:x_max]"""OpenCV使用 (x, y) 表示坐标(x=水平方向,y=垂直方向)图像数组索引顺序为 [行, 列] → 对应 [y, x]"""# 3. 图片输出cv2.imshow('image_np', image_np) # 显示带矩形框的原图cv2.imshow('ROI_imge', ROI_imge) # 显示裁剪出的ROI区域cv2.waitKey(0) # 等待按键(0表示无限等待)cv2.imwrite('ROI_imge.png', ROI_imge)# 使用matplotlib手动去看要截取的x,y的数组参数q = plt.imread(path)plt.imshow(q)plt.axis('off') # 取消坐标轴显示plt.show()except Exception as e:# 如果出错,弹出错误信息print('错误信息:', e)
cv2.imshow('image_np', image_np) # 显示带矩形框的原图
cv2.imshow('ROI_imge', ROI_imge) # 显示裁剪出的ROI区域