使用Python3 OpenCV+GStreamer调用Flir Hadron相机存显视频报错求助
问题:无法通过Python+OpenCV+GStreamer打开Flir Hadron相机
尝试用Python 3结合OpenCV与GStreamer实现Flir Hadron相机的视频显示与保存,已有可正常运行的GStreamer管道能高分辨率显示并保存视频,但Python代码执行时报错Cannot open camera. Exiting,怀疑是相机设置代码问题,求解决。
可用的GStreamer管道(显示并保存视频)
gst-launch-1.0 v4l2src io-mode=4 device=/dev/video0 do-timestamp=true ! tee name=t ! 'video/x-raw, format=UYVY, width=1920, height=1080, framerate=30/1' ! queue leaky=1 ! xvimagesink sync=false t. ! queue ! nvvidconv ! nvv4l2h265enc bitrate=8000000 ! h265parse ! qtmux ! filesink location=/home/nvidia/Desktop/RGB_$(date '+%Y-%m-%d_%H-%M-%S').mp4 -e
我使用的Python 3代码
import time import cv2 # Cam properties fps = 30. frame_width = 640 frame_height = 480 # Create capture cap = cv2.VideoCapture(0) # Set camera properties cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height) cap.set(cv2.CAP_PROP_FPS, fps) # Define the gstreamer sink gst_str_rtp = "appsrc ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5000" # Check if cap is open if cap.isOpened() is not True: print "Cannot open camera. Exiting." quit() # Create videowriter as a SHM sink out = cv2.VideoWriter(gst_str_rtp, 0, fps, (frame_width, frame_height), True) # Loop it while True: # Get the frame ret, frame = cap.read() # Check if ret is True: # Flip frame frame = cv2.flip(frame, 1) # Write to SHM out.write(frame) else: print "Camera error." time.sleep(10) cap.release()
解决方案
核心问题分析
- OpenCV默认v4l2后端无法正确识别Flir Hadron相机的UYVY格式,必须通过GStreamer管道捕获帧
- 代码存在Python 2语法错误(
print未加括号),导致Python 3环境运行异常 - 手动设置的640x480分辨率与相机原生1920x1080输出不匹配,引发格式冲突
修改后的完整代码
import time import cv2 # 构造GStreamer捕获管道,适配相机UYVY格式并转为OpenCV兼容的BGR gst_capture_str = ( "v4l2src io-mode=4 device=/dev/video0 do-timestamp=true ! " "video/x-raw, format=UYVY, width=1920, height=1080, framerate=30/1 ! " "videoconvert ! video/x-raw, format=BGR ! appsink" ) # 使用GStreamer后端初始化相机捕获 cap = cv2.VideoCapture(gst_capture_str, cv2.CAP_GSTREAMER) # 检查相机是否成功打开 if not cap.isOpened(): print("Cannot open camera. Exiting.") exit() # 构造视频保存的GStreamer管道,复用原工作管道的硬件加速编码逻辑 gst_save_str = ( "appsrc ! videoconvert ! nvvidconv ! " "nvv4l2h265enc bitrate=8000000 ! h265parse ! " "qtmux ! filesink location=/home/nvidia/Desktop/RGB_{}.mp4".format(time.strftime("%Y-%m-%d_%H-%M-%S")) ) # 初始化视频写入器 out = cv2.VideoWriter(gst_save_str, cv2.CAP_GSTREAMER, 0, 30.0, (1920, 1080), True) if not out.isOpened(): print("Cannot open video writer. Exiting.") cap.release() exit() # 主循环:读取、显示、保存帧 while True: ret, frame = cap.read() if ret: # 显示视频帧 cv2.imshow("Flir Hadron Camera", frame) # 写入视频文件 out.write(frame) # 按Q键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break else: print("Failed to read frame from camera.") time.sleep(1) break # 释放所有资源 cap.release() out.release() cv2.destroyAllWindows()
关键修改点
- 强制GStreamer后端捕获:直接传入匹配相机格式的GStreamer管道给
cv2.VideoCapture,指定cv2.CAP_GSTREAMER后端,确保正确读取UYVY格式并转成OpenCV兼容的BGR - 修复Python语法:将Python 2风格
print语句改为Python 3的print()函数 - 匹配原生分辨率:使用相机实际输出的1920x1080分辨率,避免格式不兼容
- 复用硬件加速编码:视频保存管道沿用原工作管道的
nvv4l2h265enc硬件编码器,提升编码效率 - 添加交互逻辑:增加窗口显示和按键退出功能,方便调试控制
额外验证步骤
运行以下代码确认OpenCV是否编译了GStreamer支持:
import cv2 print(cv2.getBuildInformation())
在输出中查找GStreamer条目,确保显示YES。
内容的提问来源于stack exchange,提问作者Ihssane Oubari
相关产品推荐
相关产品推荐

