将原始 OpenCV 图像传输到 FFmpeg

2024-11-08 08:43:00
admin
原创
31
摘要:问题描述:这是一个使用 OpenCV 的 python 绑定读取网络摄像头的相当简单的例子:'''capture.py''' import cv, sys cap = cv.CaptureFromCAM(0) # 0 is for /dev/video0 while Tr...

问题描述:

这是一个使用 OpenCV 的 python 绑定读取网络摄像头的相当简单的例子:

'''capture.py'''
import cv, sys
cap = cv.CaptureFromCAM(0)                    # 0 is for /dev/video0
while True :
    if not cv.GrabFrame(cap) : break
    frame = cv.RetrieveFrame(cap)
    sys.stdout.write( frame.tostring() )

现在我想将输出通过管道传输到 ffmpeg,如下所示:

$ python capture.py | ffmpeg -f image2pipe -pix_fmt bgr8 -i - -s 640x480 foo.avi

遗憾的是,我无法正确使用 ffmpeg 魔法咒语,并且它失败了

  libavutil 50.15.1 / 50.15.1
  libavcodec 52.72.2 / 52.72.2
  libav 格式 52.64。 2 / 52.64。 2
  libavdevice 52.2.0 / 52.2.0
  libavfilter 1.19.0 / 1.19.0
  libswscale 0.11. 0 / 0.11. 0
  libpostproc 51. 2. 0 / 51. 2. 0
输出 #0,avi,至‘out.avi’:
    流 #0.0:视频:flv、yuv420p、640x480、q=2-31、19660 kb/s、90k tbn、30 tbc
[image2pipe @ 0x1508640]已达到max_analyze_duration
[image2pipe @ 0x1508640]根据比特率估算时长,可能不准确
输入 #0,image2pipe,来自‘pipe:’:
  时长:N/A,比特率:N/A
    流 #0.0:视频:0x0000、bgr8、25 fps、25 tbr、25 tbn、25 tbc
swScaler:0x0 -> 640x480 是无效的缩放尺寸
  • 捕获的帧肯定是 640x480。

  • 我很确定 OpenCV 图像类型 (IplImage) 的像素顺序是 GBR,即每个通道一个字节。至少,这似乎是从相机中传出来的。

我不是 ffmpeg 专家。有人成功完成过这个吗?


解决方案 1:

经过一番折腾,我终于使用 FFmpeg rawvideo 解复用器解决了这个问题:

python capture.py | ffmpeg -f rawvideo -pixel_format bgr24 -video_size 640x480 -framerate 30 -i - foo.avi

由于原始视频中没有指定假定视频参数的标题,因此用户必须指定这些参数才能正确解码数据:

  • -framerate设置输入视频帧率。默认值为 25。

  • -pixel_format设置输入视频像素格式。默认值为yuv420p。

  • -video_size设置输入视频大小。没有默认值,因此必须明确指定此值。

这里还有一些针对高级用户的额外内容。同样的事情,但使用 VLC 将实时输出流式传输到网络,Flash 格式:

python capture.py | cvlc --demux=rawvideo --rawvid-fps=30 --rawvid-width=320 --rawvid-height=240  --rawvid-chroma=RV24 - --sout "#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}"

编辑:使用 ffmpeg 和 ffserver 创建 webm 流

python capture.py | ffmpeg -f rawvideo -pixel_format rgb24 -video_size 640x480 -framerate 25 -i - http://localhost:8090/feed1.ffm

解决方案 2:

我有点迟了,但我强大的VidGearPython 库可以自动在任何平台上将 OpenCV 帧传输到 FFmpeg 中。这是一个基本的 Python 示例:

# import libraries
from vidgear.gears import WriteGear
import cv2

output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"} #define (Codec,CRF,preset) FFmpeg tweak parameters for writer

stream = cv2.VideoCapture(0) #Open live webcam video stream on first index(i.e. 0) device

writer = WriteGear(output_filename = 'Output.mp4', compression_mode = True, logging = True, **output_params) #Define writer with output filename 'Output.mp4' 

# infinite loop
while True:
    
    (grabbed, frame) = stream.read()
    # read frames

    # check if frame empty
    if not is grabbed:
        #if True break the infinite loop
        break
    

    # {do something with frame here}
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # write a modified frame to writer
    writer.write(gray) 
       
    # Show output window
    cv2.imshow("Output Frame", frame)

    key = cv2.waitKey(1) & 0xFF
    # check for 'q' key-press
    if key == ord("q"):
        #if 'q' key-pressed break out
        break

cv2.destroyAllWindows()
# close output window

stream.release()
# safely close video stream
writer.close()
# safely close writer

来源:https ://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-with-opencv

您可以查看VidGear Docs以了解更多高级应用程序和功能。

希望有帮助!

解决方案 3:

不确定这是 Mac OS 特有的还是 python3 特有的,但我需要将框架转换为字符串才能使其为我工作,如下所示:

sys.stdout.write(str(frame.tostring()))

解决方案 4:

我花了一个小时才弄清楚,默认情况下,Windows 管道不是二进制的。这会导致某些字节(特别是换行符)被修改/省略,并且由于帧大小不稳定,因此生成的视频会缓慢移动。

为了解决这个问题,修改后的 python 文件:

"""
videoCapture.py
"""
import cv2, sys
import time

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

cap = cv2.VideoCapture(0)                    # 0 is for /dev/video0
while True :
    ret, frm = cap.read()
    sys.stdout.write( frm.tostring() )

要测试管道传输原始视频是否成功,请使用 ffplay。请确保您指定的帧速率高于管道传输的帧速率,否则视频将开始滞后

python videoCapture.py | ffplay -f rawvideo -pix_fmt bgr24 -s 640x480 -framerate 40 -i -

解决方案 5:

如果传递 bgr8 OpenCV 帧,仍然需要-pix_fmt bgr24在 FFmpeg 管道中进行设置。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用