You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实时视频人眼检测项目首次检测到人眼后自动设置ROI问题咨询

人眼检测ROI锁定实现方案

方案一:自动锁定首次检测到的眼睛ROI

实现逻辑

  • 新增两个状态变量:roi_locked(布尔值,初始为False,标识是否已锁定ROI)、eye_roi_coord(存储ROI在原图的左上角、宽高坐标,初始为None)
  • 未锁定ROI时,保留原有的「人脸检测→人眼检测」逻辑
  • 首次成功检测到有效眼睛时,将所有眼睛的外接区域合并为一个大ROI,记录坐标并锁定ROI
  • 锁定后跳过人脸检测步骤,直接裁剪对应ROI区域执行人眼检测
  • 可新增容错:连续10帧在ROI内未检测到眼睛时自动解锁,重新走全图检测流程,适配人员小范围移动的场景

方案二:手动选择指定ROI

实现逻辑

  • 程序启动后先读取第一帧画面,调用OpenCV原生的cv2.selectROI接口,用户直接用鼠标框选需要检测的眼睛区域即可
  • 后续所有帧都只在框选的固定区域内执行人眼检测,完全跳过人脸检测步骤,适配固定机位、人员位置相对固定的场景

示例代码

import cv2
import time

# 配置开关:True为自动锁定ROI,False为手动选择ROI
AUTO_ROI = True

# 状态变量
roi_locked = False
eye_roi = None  # 存储格式:(x, y, w, h)
miss_count = 0
MISS_THRESHOLD = 10  # 连续10帧检测不到就自动重置ROI

def nothing(x):
    pass

# 此处保留你原有的detect_faces、detect_eyes、cut_eyebrows、blob_process函数
# 以下是修改后的main函数
def main():
    global roi_locked, eye_roi, miss_count
    cap = cv2.VideoCapture(0)
    time.sleep(1.000)
    cv2.namedWindow('image')
    cv2.createTrackbar('threshold', 'image', 0, 255, nothing)
    
    # 手动选择ROI逻辑
    if not AUTO_ROI:
        _, frame = cap.read()
        # 调用selectROI接口,用户框选后按空格/回车确认
        eye_roi = cv2.selectROI('image', frame, showCrosshair=True, fromCenter=False)
        cv2.destroyWindow('image')
        cv2.namedWindow('image')
        roi_locked = True

    while True:
        _, frame = cap.read()
        threshold = cv2.getTrackbarPos('threshold', 'image')
        
        if not roi_locked:
            # 未锁定ROI时走原有人脸检测逻辑
            face_frame = detect_faces(frame, face_cascade)
            if face_frame is not None:
                eyes = detect_eyes(face_frame, eye_cascade)
                valid_eyes = [e for e in eyes if e is not None]
                if len(valid_eyes) >= 1:
                    # 首次检测到有效眼睛,锁定ROI
                    x_min = min([e[0] for e in valid_eyes])
                    y_min = min([e[1] for e in valid_eyes])
                    x_max = max([e[0] + e[2] for e in valid_eyes])
                    y_max = max([e[1] + e[3] for e in valid_eyes])
                    # 给ROI加20像素边距,避免边缘丢失目标
                    pad = 20
                    eye_roi = (
                        max(0, x_min - pad),
                        max(0, y_min - pad),
                        x_max - x_min + 2*pad,
                        y_max - y_min + 2*pad
                    )
                    roi_locked = True
                    # 处理当前帧的眼睛
                    for eye in valid_eyes:
                        eye = cut_eyebrows(eye)
                        keypoints = blob_process(eye, threshold, detector)
                        eye = cv2.drawKeypoints(eye, keypoints, eye, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
        else:
            # 已锁定ROI,直接裁剪区域检测
            x, y, w, h = eye_roi
            roi_area = frame[y:y+h, x:x+w]
            # 直接在ROI区域做人眼检测,不需要先检测人脸
            eyes = detect_eyes(roi_area, eye_cascade)
            valid_eyes = [e for e in eyes if e is not None]
            if len(valid_eyes) == 0:
                miss_count += 1
                # 连续丢失超过阈值,自动解锁ROI
                if miss_count >= MISS_THRESHOLD and AUTO_ROI:
                    roi_locked = False
                    miss_count = 0
                    eye_roi = None
            else:
                miss_count = 0
                for eye in valid_eyes:
                    eye = cut_eyebrows(eye)
                    keypoints = blob_process(eye, threshold, detector)
                    # 坐标映射回原图绘制
                    eye_x = x + eye[0]
                    eye_y = y + eye[1]
                    cv2.drawKeypoints(frame[eye_y:eye_y+eye[3], eye_x:eye_x+eye[2]], 
                                      keypoints, 
                                      frame[eye_y:eye_y+eye[3], eye_x:eye_x+eye[2]], 
                                      (0, 0, 255), 
                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
            # 可选:在原图绘制ROI边界,方便调试
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

        cv2.imshow('image', frame)
        # 按r键手动重置ROI
        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):
            break
        elif key == ord('r'):
            roi_locked = False
            miss_count = 0
            eye_roi = None
    cap.release()
    cv2.destroyAllWindows()

注意事项

  • 自动ROI方案适合人员位置相对固定、不会大幅移动的场景,如果人员会大范围移动,可以搭配轻量的目标跟踪算法(比如CSRT、KCF)实时更新ROI坐标,稳定性会更高
  • 手动ROI方案适合固定机位的工业场景,不需要依赖人脸检测,运行效率更高

内容的提问来源于stack exchange,提问作者SmashAI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:48:01