使用Basler相机与Python录制视频(替代单帧保存)的技术问询
嘿,我之前也用Basler相机做过视频录制的需求,你的单帧捕获代码已经搭好基础了,只需要补上视频帧的编码和持续写入逻辑就行。下面给你两种实用的实现方案,都是基于你现有代码修改的:
方案1:用OpenCV实现流式视频录制(适合长时间录制)
OpenCV的VideoWriter支持边采集边写入,不会占用过多内存,很适合长时间录制场景。你只需要在现有代码基础上添加几行:
首先导入OpenCV库,完善相机参数配置,最后加入循环采集和写入逻辑:
import os import pypylon import cv2 import time start = time.time() print('Sampling rate (Hz):') fsamp = input() fsamp = float(fsamp) time_exposure = 1000000 * (1/fsamp) # 查找并初始化相机 available_cameras = pypylon.factory.find_devices() cam = pypylon.factory.create_device(available_cameras[0]) cam.open() # 配置相机参数:曝光时间、帧率 cam.properties['ExposureTime'] = time_exposure cam.properties['AcquisitionFrameRateEnable'] = True cam.properties['AcquisitionFrameRate'] = fsamp # 获取相机分辨率 width = cam.properties['Width'] height = cam.properties['Height'] # 创建VideoWriter对象:输出文件、编码格式、帧率、分辨率 # 编码格式可根据平台调整:Windows用XVID,Mac/Linux用MP4V fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('basler_recording.avi', fourcc, fsamp, (width, height)) try: print("开始录制视频,按'q'键停止...") # 开启连续采集模式 cam.start_grabbing(pypylon.factory.GrabStrategy_LatestImageOnly) while cam.is_grabbing(): # 获取一帧图像,超时5秒抛异常 grab_result = cam.retrieve_result(5000, pypylon.TimeoutHandling_ThrowException) if grab_result.GrabSucceeded(): # 转换图像格式:Basler默认输出单通道灰度,转成OpenCV需要的BGR格式 frame = grab_result.Array if len(frame.shape) == 2: frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) # 写入视频文件 out.write(frame) # 实时预览(可选,不想看可以注释掉) cv2.imshow('Recording', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放当前帧资源 grab_result.Release() finally: # 收尾工作:停止采集、释放视频写入器、关闭预览窗口 cam.stop_grabbing() out.release() cv2.destroyAllWindows() print(f"录制完成,视频已保存到basler_recording.avi")
关键注意点:
- 编码格式:不同平台支持的编码不同,
XVID在Windows上兼容性好,MP4V适合生成MP4格式(把输出文件名改成.mp4即可)。 - 图像格式转换:Basler相机默认输出单通道灰度图,需要转成3通道BGR才能被
VideoWriter正确写入。如果你的相机是彩色的,可以跳过这一步。 - 帧率匹配:相机设置的
AcquisitionFrameRate要和VideoWriter的帧率参数一致,否则视频会出现快进/慢放的情况。
方案2:用imageio批量写入视频(适合短时长录制)
如果你只需要录制短时间的视频(比如10秒内),可以用你已经导入的imageio库,先把所有帧存到内存列表里,最后一次性写入:
import os import pypylon from imageio import mimwrite import cv2 import time start = time.time() print('Sampling rate (Hz):') fsamp = input() fsamp = float(fsamp) time_exposure = 1000000 * (1/fsamp) available_cameras = pypylon.factory.find_devices() cam = pypylon.factory.create_device(available_cameras[0]) cam.open() cam.properties['ExposureTime'] = time_exposure cam.properties['AcquisitionFrameRateEnable'] = True cam.properties['AcquisitionFrameRate'] = fsamp # 存储所有帧的列表 frames = [] record_duration = 10 # 设置录制时长(秒) try: print(f"开始录制视频,将持续{record_duration}秒...") cam.start_grabbing(pypylon.factory.GrabStrategy_LatestImageOnly) start_record_time = time.time() while cam.is_grabbing() and (time.time() - start_record_time) < record_duration: grab_result = cam.retrieve_result(5000, pypylon.TimeoutHandling_ThrowException) if grab_result.GrabSucceeded(): frame = grab_result.Array # 灰度图转RGB(imageio需要RGB格式) if len(frame.shape) == 2: frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) frames.append(frame) grab_result.Release() finally: cam.stop_grabbing() # 写入视频 mimwrite('basler_recording.mp4', frames, fps=fsamp) print(f"录制完成!共捕获{len(frames)}帧,视频已保存到basler_recording.mp4")
这种方法的优缺点:
- 优点:代码更简洁,不需要实时处理窗口,适合批量录制短视频。
- 缺点:所有帧都存在内存里,录制时间过长会导致内存占用过高,不建议超过30秒的录制。
内容的提问来源于stack exchange,提问作者Rishabh sharma
相关产品推荐
相关产品推荐

