树莓派使用OpenCV多进程实现多摄像头录像时进程无法启动问题求助
核心问题原因
- 主进程检测摄像头时占用了
VideoCapture设备句柄未释放,Linux系统下摄像头设备是独占模式,子进程无法再次打开被占用的设备 - 主进程启动子进程后没有保持运行,主进程退出时会自动终止所有未完成的子进程
- 子进程逻辑中未添加
VideoCapture打开状态校验,出错时无日志输出,无法定位问题 - 缺少多进程必需的入口保护判断
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
相关产品推荐
相关产品推荐

