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

如何停止cv2人体检测程序的运行 避免死循环阻塞主程序执行

人体检测功能模块重构方案

核心问题说明

你遇到的阻塞问题源于检测代码把视频读取、逻辑处理、窗口渲染全耦合在同一个无限循环里,只要调用就会占满当前线程,导致主程序后续代码无法执行。下面提供两种可直接落地的解决方案:


方案1:封装为单帧处理工具(最推荐)

把核心检测逻辑拆成独立类/函数,每次调用仅处理单帧图像,循环逻辑完全交给主程序控制,耦合度最低、灵活度最高。

重构后的检测模块代码(pose_detector.py)

import cv2
import mediapipe as mp

mpDraw = mp.solutions.drawing_utils
mppose = mp.solutions.pose

class PoseDetector:
    def __init__(self):
        self.pose = mppose.Pose()
    
    def process_frame(self, img):
        # 输入为BGR格式的图像帧,返回关键点列表和绘制后的图像
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        results = self.pose.process(imgRGB)
        lmlist = []
        if results.pose_landmarks:
            mpDraw.draw_landmarks(img, results.pose_landmarks, mppose.POSE_CONNECTIONS)
            h, w, c = img.shape
            for id, lm in enumerate(results.pose_landmarks.landmark):
                cx, cy = int(lm.x*w), int(lm.y*h)
                lmlist.append([id, cx, cy])
            # 绘制鼻关键点
            if lmlist:
                cv2.circle(img, (lmlist[0][1], lmlist[0][2]), 15, (255, 0, 255), cv2.FILLED)
        return lmlist, img

主程序调用示例

import cv2
import time
from pose_detector import PoseDetector

if __name__ == "__main__":
    detector = PoseDetector()
    cap = cv2.VideoCapture('open cv/squidgamee/3.mp4')
    cap.set(3, 400)
    cap.set(4, 800)
    ptime = 0
    
    # 主程序自主控制循环,可随时加终止条件
    while True:
        succ, img = cap.read()
        # 视频读完自动退出
        if not succ:
            break 
        lmlist, processed_img = detector.process_frame(img)
        
        # 此处可插入主程序其他业务逻辑,不会被阻塞
        if lmlist:
            print(lmlist[0])
            # 示例:满足自定义条件直接终止检测
            # if lmlist[0][1] > 300:
            #     break
        
        # 渲染逻辑也可自主控制
        ctime = time.time()
        fps = 1/(ctime-ptime)
        ptime = ctime
        cv2.putText(processed_img, str(int(fps)), (70, 50), cv2.FONT_HERSHEY_COMPLEX, 3, (255,255,0), 3)
        cv2.imshow("image", processed_img)
        key = cv2.waitKey(1)
        if key == ord('q'):
            break
    
    # 后续主程序代码可正常执行
    cap.release()
    cv2.destroyAllWindows()
    print("检测结束,执行主程序后续逻辑")

方案2:多线程运行检测逻辑

如果需要检测任务后台运行、不影响主程序同步执行其他逻辑,可以把整个检测循环放到子线程中运行。

调整后的检测模块代码(pose_detector.py)

import cv2
import mediapipe as mp
import time

mpDraw = mp.solutions.drawing_utils
mppose = mp.solutions.pose
pose = mppose.Pose()

def run_pose_detection(video_path, exit_flag=None):
    cap = cv2.VideoCapture(video_path)
    cap.set(3, 400)
    cap.set(4, 800)
    ptime =0
    while True:
        # 支持主程序主动发送信号终止检测
        if exit_flag is not None and exit_flag.is_set():
            break
        succ, img = cap.read()
        if not succ:
            break
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        results = pose.process(imgRGB)
        if results.pose_landmarks:
            mpDraw.draw_landmarks(img, results.pose_landmarks, mppose.POSE_CONNECTIONS)
            lmlist= []
            for id, lm in enumerate(results.pose_landmarks.landmark):
                h, w, c = img.shape
                cx ,  cy = int(lm.x*w), int(lm.y*h)
                lmlist.append([id, cx, cy])
                cv2.circle(img, (lmlist[0][1], lmlist[0][2]), 15 , (255, 0, 255), cv2.FILLED)
            print(lmlist[0])
        ctime = time.time()
        fps = 1/(ctime-ptime)
        ptime = ctime
        cv2.putText(img, str(int(fps)), (70, 50), cv2.FONT_HERSHEY_COMPLEX, 3, (255,255,0), 3)
        cv2.imshow("image", img)
        key= cv2.waitKey(1)
        if key == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

主程序调用示例

import threading
from pose_detector import run_pose_detection

if __name__ == "__main__":
    # 创建退出信号,主程序可主动终止检测
    exit_flag = threading.Event()
    detect_thread = threading.Thread(target=run_pose_detection, args=('open cv/squidgamee/3.mp4', exit_flag))
    detect_thread.start()
    
    # 主程序其他逻辑可直接执行,不会被阻塞
    print("主程序其他逻辑正在运行...")
    # 需要主动停止检测时调用即可
    # exit_flag.set()
    # 等待检测线程结束
    detect_thread.join()
    print("检测结束,主程序继续执行")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:36:09