使用Python和GStreamer实现摄像头画面显示与保存

ChatGPT4o 使用 ChatGPT 4o 回答

问题:

这是读取摄像头显示的代码 gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! "video/x-raw(memory:NVMM),width=4032,height=3040,framerate=30/1" ! nvvidconv ! "video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1" ! nvoverlaysink 这是读取摄像头保存图片的代码 gst-launch-1.0 -e nvarguscamerasrc num-buffers=20 sensor-id=0 ! "video/x-raw(memory:NVMM),width=4032,height=3040,framerate=30 读取摄像头保存视频的代码 gst-launch-1.0 -e nvarguscamerasrc sensor-id=0 ! "video/x-raw(memory:NVMM),width=4032,height=3040,framerate=30/1" ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=rpi_v3_imx477_cam0.mp4 根据以上代码,写一段代码显示摄像头画面,并按s键保存图片和视频,名称加上时间戳,按q键退出

回答:

要实现一个程序,能够显示摄像头画面,并在按下s键时保存图片和视频(文件名带时间戳),按下q键退出,我们可以使用Python结合GStreamer和OpenCV来实现。以下是一个示例代码:

import cv2
import time
import subprocess
import threading

# GStreamer pipeline for displaying the camera feed
gst_display = "nvarguscamerasrc sensor-id=0 ! video/x-raw(memory:NVMM),width=4032,height=3040,framerate=30/1 ! nvvidconv ! video/x-raw,format=BGR ! appsink"
# GStreamer pipeline for saving video
gst_save_video = "nvarguscamerasrc sensor-id=0 ! video/x-raw(memory:NVMM),width=4032,height=3040,framerate=30/1 ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location={}"

# Function to save video
def save_video(filename):
    subprocess.run(gst_save_video.format(filename), shell=True)

# Start the camera feed
cap = cv2.VideoCapture(gst_display, cv2.CAP_GSTREAMER)

if not cap.isOpened():
    print("Error: Could not open camera.")
    exit()

video_thread = None
is_recording = False

while True:
    ret, frame = cap.read()
    if not ret:
        print("Error: Could not read frame.")
        break

    cv2.imshow("Camera Feed", frame)

    key = cv2.waitKey(1) & 0xFF

    if key == ord('s'):
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        image_filename = f"image_{timestamp}.jpg"
        video_filename = f"video_{timestamp}.mp4"

        # Save image
        cv2.imwrite(image_filename, frame)
        print(f"Saved image: {image_filename}")

        # Start saving video in a separate thread
        if not is_recording:
            is_recording = True
            video_thread = threading.Thread(target=save_video, args=(video_filename,))
            video_thread.start()
            print(f"Started recording video: {video_filename}")

    elif key == ord('q'):
        break

# Cleanup
cap.release()
cv2.destroyAllWindows()

# Stop video recording if it's still running
if video_thread is not None:
    video_thread.join()

说明:

  1. GStreamer管道:我们使用GStreamer管道来获取摄像头的实时视频流,并通过OpenCV显示。
  2. 按键处理
    • 按下s键时,程序会保存当前帧为图片,并启动一个线程来保存视频。
    • 按下q键时,程序会退出。
  3. 时间戳:文件名中包含当前的时间戳,以确保每次保存的文件名都是唯一的。
  4. 多线程:使用线程来处理视频保存,以避免阻塞主线程。

注意事项:

  • 确保你的系统上安装了OpenCV和GStreamer,并且能够正确识别摄像头。
  • 根据