如何在摄像头采集的400x300主窗口中获取带红框的ROI帧?
解决方法:在摄像头帧中显示带红色边框的ROI
原代码的问题分析
- 摄像头分辨率设置错误:需求是400x300的主窗口,你把
CAP_PROP_FRAME_WIDTH设为300、CAP_PROP_FRAME_HEIGHT设为400,搞反了宽高,导致ROI的右边界超出帧宽度,无法正常显示。 - 掩码使用逻辑错误:掩码是单通道灰度图,用三通道颜色
(0,0,255)绘制完全没必要,且cv2.add的参数用法不符合你要显示ROI加边框的需求。 - ROI坐标计算错误:ROI尺寸是320x240,起始点(30,30),结束坐标应为
(30+320, 30+240) = (350, 270),原代码写的(320,240)会把ROI尺寸缩小到290x210,不符合要求。
正确实现方式
方法1:直接在帧上绘制红色边框并显示ROI区域
这种方法最直接,在原帧上画出ROI的红色边框,可选择显示带边框的完整帧或单独显示ROI区域:
import numpy as np import cv2 capture = cv2.VideoCapture(0) if not capture.isOpened(): raise Exception("Camera not connected") # 设置正确的分辨率:宽400,高300 capture.set(cv2.CAP_PROP_FRAME_WIDTH, 400) capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 300) # ROI参数:起始坐标(x,y),宽度,高度 roi_x, roi_y = 30, 30 roi_w, roi_h = 320, 240 # 计算ROI结束坐标 roi_end_x = roi_x + roi_w roi_end_y = roi_y + roi_h while True: ret, frame = capture.read() if not ret: break # 在帧上绘制红色边框:BGR格式红色为(0,0,255),边框厚度设为2 cv2.rectangle(frame, (roi_x, roi_y), (roi_end_x, roi_end_y), (0, 0, 255), 2) # 提取ROI区域 roi = frame[roi_y:roi_end_y, roi_x:roi_end_x] # 显示主窗口(带边框的完整帧)和ROI窗口 cv2.imshow("Main Window (400x300)", frame) cv2.imshow("ROI (320x240)", roi) if cv2.waitKey(10) == 27: # 按ESC键退出 break capture.release() cv2.destroyAllWindows()
方法2:突出ROI区域(其他区域变暗)
如果需要更突出ROI,可以把非ROI区域调暗,再叠加红色边框:
import numpy as np import cv2 capture = cv2.VideoCapture(0) if not capture.isOpened(): raise Exception("Camera not connected") capture.set(cv2.CAP_PROP_FRAME_WIDTH, 400) capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 300) roi_x, roi_y = 30, 30 roi_w, roi_h = 320, 240 roi_end_x = roi_x + roi_w roi_end_y = roi_y + roi_h while True: ret, frame = capture.read() if not ret: break # 创建一个变暗的帧副本,alpha值越小越暗 dimmed_frame = cv2.convertScaleAbs(frame, alpha=0.3) # 将ROI区域替换为原帧的清晰图像 dimmed_frame[roi_y:roi_end_y, roi_x:roi_end_x] = frame[roi_y:roi_end_y, roi_x:roi_end_x] # 绘制红色边框 cv2.rectangle(dimmed_frame, (roi_x, roi_y), (roi_end_x, roi_end_y), (0, 0, 255), 2) cv2.imshow("Main Window with Highlighted ROI", dimmed_frame) if cv2.waitKey(10) == 27: break capture.release() cv2.destroyAllWindows()
关键说明
- OpenCV使用BGR颜色格式,因此红色用
(0,0,255)表示。 - 提取ROI的语法是
frame[y_start:y_end, x_start:x_end],注意y轴在前、x轴在后。 - 部分摄像头可能不支持自定义分辨率,设置后可通过
capture.get(cv2.CAP_PROP_FRAME_WIDTH)和capture.get(cv2.CAP_PROP_FRAME_HEIGHT)验证实际生效的分辨率。
内容的提问来源于stack exchange,提问作者Joon
相关产品推荐
相关产品推荐

