2. 摄像头实时视频采集
任务目标
在Jetson Nano上接入CSI或USB摄像头,使用OpenCV读取实时视频流并在屏幕上显示。本案例覆盖两种摄像头接入方式,并给出帧率统计以便确认采集性能。
环境依赖
- Jetson Nano(JetPack 4.6+,已安装OpenCV 4.x预编译版本)
- CSI摄像头(如IMX219)或USB摄像头(UVC协议)
- Python 3.6+,OpenCV Python绑定(
cv2)
关键完整代码
import cv2
import sys
import time
def open_camera(use_csi=True):
"""根据摄像头类型打开视频流"""
if use_csi:
# CSI摄像头:使用GStreamer管道,Jetson专用
gst_str = (
"nvarguscamerasrc ! "
"video/x-raw(memory:NVMM), width=1280, height=720, framerate=30/1 ! "
"nvvidconv flip-method=2 ! "
"video/x-raw, width=1280, height=720, format=BGRx ! "
"videoconvert ! video/x-raw, format=BGR ! appsink"
)
cap = cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
else:
# USB摄像头:直接使用V4L2后端
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
return cap
def main():
# 默认使用CSI摄像头;若使用USB摄像头,将参数改为False
use_csi = len(sys.argv) < 2 or sys.argv[1].lower() != "usb"
cap = open_camera(use_csi)
if not cap.isOpened():
print("错误:无法打开摄像头")
sys.exit(1)
print("摄像头已打开,按 'q' 键退出")
frame_count = 0
start_time = time.time()
fps = 0.0
while True:
ret, frame = cap.read()
if not ret:
print("错误:读取视频帧失败")
break
# 计算并显示实时帧率
frame_count += 1
if frame_count % 10 == 0:
elapsed = time.time() - start_time
fps = frame_count / elapsed
cv2.putText(frame, f"FPS: {fps:.1f}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow("Jetson Nano Camera", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
print(f"采集结束,平均帧率约 {fps:.1f} FPS")
if __name__ == "__main__":
main()
运行方式
# CSI摄像头(默认)
python3 camera_capture.py
# USB摄像头
python3 camera_capture.py usb
验证方法与判定标准
- 画面显示:运行后弹出名为“Jetson Nano Camera”的窗口,实时显示摄像头画面,无卡顿或花屏。
- 帧率指标:窗口左上角显示绿色FPS数值。CSI摄像头在720p下通常可达30 FPS;USB摄像头视型号而定,一般不低于15 FPS即视为正常。
- 退出机制:按键盘
q键,窗口关闭,终端打印平均帧率后程序正常结束。 - 错误排查:若提示“无法打开摄像头”,检查摄像头连接及权限(
ls /dev/video*确认设备节点),CSI摄像头需确认排线连接牢固。
常见问题
- CSI摄像头画面倒置:修改GStreamer管道中的
flip-method值(0=不翻转,1=水平翻转,2=垂直翻转,3=双向翻转),根据安装方向调整。 - USB摄像头无法打开:确认没有其他进程占用摄像头(如
cheese),或尝试将设备编号从0改为1。 - 帧率偏低:降低分辨率(如改为640x480)可提升帧率;关闭桌面环境后通过SSH运行可释放GPU资源。