繁体   English   中英

Stream 来自使用 openCV 和 Python 的相机的 RAW8 视频 [Windows]

[英]Stream RAW8 video from camera using openCV and Python [Windows]

我们有一台可以 1920x1080 流式传输 RAW8 视频的相机。 使用的 GUID 是灰色的。 我们可以通过以下命令在 Windows 上使用 ffmpeg 从该摄像机获取 stream 视频:

ffmpeg -f dshow -pix_fmt gray -video_size 1920x1080 -i video="CAM0" -f nut - | ffplay -

我们现在正尝试使用以下代码片段使用 OpenCV 从该相机抓取图像,但它无法抓取任何帧(frame_grabbed 始终为 false)

import cv2
import numpy as np

# reading the video from CAM0
source = cv2.VideoCapture(1)

height = 1920
width = 1080

source.set(cv2.CAP_PROP_FRAME_WIDTH, width)
source.set(cv2.CAP_PROP_FRAME_HEIGHT, height)


image = np.zeros([height, width, 3], np.uint8)

while True:
    # Extracting the frames
    frame_grabbed , image = source.read()

    if (frame_grabbed ):
        colour1 = cv2.cvtColor(image, cv2.COLOR_BayerRG2BGR)
        cv2.imshow("Demosaiced image", colour1)
    else:
        print("No images grabbed")

#Exit on q
    key = cv2.waitKey(1)
    if key == ord("q"):
       break

# closing the window
cv2.destroyAllWindows()
source.release()

我们在这里错过了什么吗?

然后我们发现这个帖子到 pipe ffmpeg output 到 python( 链接)。 但是,当我们传递如下命令时:

command = [ 'ffmpeg.exe',
            '-f', 'dshow',
            '-i', 'video="CAM0"',
            '-pix_fmt', 'gray',
            '-video_size','1920x1080'
            '-f', 'nut', '-']

它的投掷

在视频类型的源设备中找不到名称为 ["CAM0"] 的视频设备。 video="CAM0": I/O 错误

我已经使用以下命令验证了相机是否存在:

command = [ 'ffmpeg.exe',
            '-list_devices', 'true',
            '-f', 'dshow',
            '-i', 'dummy']

这将检测 CAM0,如下所示:

ffmpeg version 5.0.1-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 11.2.0 (Rev7, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab 
--enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
[dshow @ 000001ea39e40600] "HP HD Camera" (video)
[dshow @ 000001ea39e40600]   Alternative name "@device_pnp_\\?\usb#vid_04f2&pid_b6bf&mi_00#6&1737142c&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 000001ea39e40600] "CAM0" (video)
[dshow @ 000001ea39e40600]   Alternative name "@device_pnp_\\?\usb#vid_0400&pid_0011&mi_00#7&1affbd5b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"

简而言之,我们能够使用 ffmpeg 命令行捕获视频,但无法使用 OpenCV videocapture 或 opencv 中的 ffmpeg 捕获任何帧。任何指针?

谢谢!

我不知道为什么使用 OpenCV 读取帧不起作用,但我们可以改用 FFmpeg CLI。

  • 将 FFmpeg 作为子进程执行,并将 output 设置为stdout pipe。
  • stdout pipe 读取原始视频帧,并将每个帧转换为 1920x1080 uint8 NumPy 数组。

代码示例:

import cv2
import numpy as np
import subprocess as sp

width = 1920
height = 1080

ffmpeg_command = ['ffmpeg',  # Make sure ffmpeg.exe is in the execution path
                  '-f', 'dshow',  # The input format is dshow (camera)
                  '-video_size', f'{width}x{height}',  # input resolution is 1920x1080
                  '-pixel_format', 'gray',  # input pixel format is gray
                  '-i', 'video=CAM0',  # May also try 'video="CAM0"'
                  '-f', 'rawvideo',  # The output format is rawvideo
                  '-pix_fmt', 'gray',  # The output pixel format is gray
                  'pipe:']  # Output the video to stdout pipe

# Open sub-process that gets in_stream as input and uses stdout as an output PIPE.
ffmpeg_process = sp.Popen(ffmpeg_command, stdout=sp.PIPE)

while True:
    # Read width*height bytes from stdout (1 frame)
    raw_frame = ffmpeg_process.stdout.read(width*height)

    if len(raw_frame) != (width*height):
        print('Error reading frame!!!')  # Break the loop in case of an error (too few bytes were read).
        break

    # Convert the bytes read into a NumPy array, and reshape it to video frame dimensions
    frame = np.frombuffer(raw_frame, np.uint8).reshape((height, width))

    # Show the video frame
    cv2.imshow('frame', frame)
    key = cv2.waitKey(1)
    if key == ord("q"):
        break

ffmpeg_process.stdout.close();  # Closing stdout pipe also terminates FFmpeg sub-process.
cv2.destroyAllWindows()

尝试使用'rawvide'作为 output 格式。 您可能需要将所有相机选项移动到-i参数的左侧。

如果你需要一种快速而肮脏的方式,你可以试试我的ffmpegio package

import ffmpegio

show_log = True

# if you have to record for a fixed duration 
t_record = 5
fs,F = ffmpegio.video.read('video=CAM0',f_in='dshow',
                           'pix_fmt='gray', video_size_in='1920x1080', t=5,
                           show_log=show_log)

# if you need to stream input
with ffmpegio.open('video=CAM0','rv', f_in='dshow',
                   'pix_fmt_in='gray', video_size_in='1920x1080',
                   show_log=show_log) as cam:
    for frame in cam:
        # frame = np.array of shape (1x)1920x1080x1 (I think, reshape as needed)

如果您需要这方面的帮助,请随时在 GitHub 讨论板上创建一个线程(不要在此处造成混乱)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM