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

树莓派使用OpenCV多进程实现多摄像头录像时进程无法启动问题求助

核心问题原因

  1. 主进程检测摄像头时占用了VideoCapture设备句柄未释放,Linux系统下摄像头设备是独占模式,子进程无法再次打开被占用的设备
  2. 主进程启动子进程后没有保持运行,主进程退出时会自动终止所有未完成的子进程
  3. 子进程逻辑中未添加VideoCapture打开状态校验,出错时无日志输出,无法定位问题
  4. 缺少多进程必需的入口保护判断if __name__ == "__main__",可能导致子进程启动时重复执行初始化逻辑

修复步骤

  • 主进程检测完摄像头可用性后立即释放检测用的VideoCapture句柄
  • 主进程启动子进程后添加阻塞逻辑,避免提前退出
  • 子进程内添加设备打开状态校验和异常捕获
  • 添加入口保护逻辑,防止子进程重复执行启动代码
  • 优化子进程逻辑,避免每次分段录像重复打开摄像头,减少设备占用冲突

修复后参考代码

import multiprocessing
import cv2 as cv
import time
import os
import shutil

# 替换为你的原有常量定义
CAPTURE_TIME = 300
VIDEO_STORE = "./videos"
LOG_CODE_APP_START = 1
LOG_CODE_NEW_VIDEO = 2
LOG_CODE_VIDEO_SAVED = 3

camera_index = []

# 你的原有工具函数
def log(code):
    print(f"Log: {code}")

def log_error(e):
    print(f"Error: {str(e)}")

def get_time_string():
    return time.strftime("%Y%m%d_%H%M%S", time.localtime())

def get_video_stream_height_width(cap):
    return int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)), int(cap.get(cv.CAP_PROP_FRAME_WIDTH))

def video_capture(camera=None):
    start_time = time.time()
    # 子进程内只打开一次摄像头即可,不需要每次循环重复打开
    capture = cv.VideoCapture(camera)
    capture.set(cv.CAP_PROP_FRAME_WIDTH, 800)
    capture.set(cv.CAP_PROP_FRAME_HEIGHT, 600)
    # 新增打开状态校验
    if not capture.isOpened():
        print(f"摄像头{camera}打开失败")
        return
    while True:
        log(LOG_CODE_NEW_VIDEO)
        file_name = 'camera_' + str(camera + 1) + '_' + get_time_string() + '.avi'
        fourcc = cv.VideoWriter_fourcc(*'XVID')
        height, width = get_video_stream_height_width(capture)
        out = cv.VideoWriter(file_name, fourcc, 20.0, (width, height))
        while int(time.time() - start_time) < CAPTURE_TIME:
            ret, frame = capture.read()
            if ret:
                out.write(frame)
        out.release()
        start_time = time.time()
        try:
            if not os.path.exists(VIDEO_STORE):
                os.mkdir(VIDEO_STORE)
            shutil.move(file_name, os.path.join(VIDEO_STORE, file_name))
            log(LOG_CODE_VIDEO_SAVED)
        except Exception as e:
            print("Exception")
            log_error(e)
    capture.release()

def init():
    log(LOG_CODE_APP_START)
    for index in range(0, 9):
        camera_check = cv.VideoCapture(index)
        if camera_check is None or not camera_check.isOpened():
            continue
        else:
            camera_index.append(index)
        # 新增:检测完成立即释放设备句柄
        camera_check.release()

    print(camera_index)
    processes = []
    for camera in camera_index:
        video_process = multiprocessing.Process(name=str(camera), target=video_capture, kwargs={'camera': camera})
        video_process.daemon = True
        processes.append(video_process)

    for process in processes:
        print("Starting processes")
        process.start()

    # 新增:主进程阻塞保持运行
    for process in processes:
        process.join()

if __name__ == "__main__":
    init()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:45:03