2011-04-28 97 views
23

下面是使用的OpenCV的Python绑定阅读掀起了网络摄像头,一个非常简单的例子:管原始OpenCV的图像FFmpeg的

'''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 
    libavformat 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 
Output #0, avi, to 'out.avi': 
    Stream #0.0: Video: flv, yuv420p, 640x480, q=2-31, 19660 kb/s, 90k tbn, 30 tbc 
[image2pipe @ 0x1508640]max_analyze_duration reached 
[image2pipe @ 0x1508640]Estimating duration from bitrate, this may be inaccurate 
Input #0, image2pipe, from 'pipe:': 
    Duration: N/A, bitrate: N/A 
    Stream #0.0: Video: 0x0000, bgr8, 25 fps, 25 tbr, 25 tbn, 25 tbc 
swScaler: 0x0 -> 640x480 is invalid scaling dimension 
  • 捕获的帧肯定是640x480。
  • 我很确定OpenCV图像类型(IplImage)的像素顺序是GBR,每个通道一个字节。至少,这似乎是从相机中脱颖而出。

我不是ffmpeg大师。有没有人成功做到这一点?

+2

哦,男人! 输出到ffmpeg的想法非常聪明! – Mehran 2013-10-13 23:13:15

回答

29

拿了一串摆弄,但我理解了它使用的FFmpeg rawvideo demuxer

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和创建WEBM流ffserver的

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

是否有其他人无法获得ffmpeg采取输出帧率(在这种情况下后者“-r 30”)?无论我做什么,我的速度都是60fps。由于摄像机硬件导致输入帧速率为30fps,因此可用于慢动作视频。一根筋。 – BrianTheLion 2011-05-04 17:04:10

+1

总体而言,VLC看起来比ffmpeg/ffserver组合更稳定。 ffserver对我保持segfault-ing。 – BrianTheLion 2011-05-06 16:28:02

+0

让我们[在聊天中继续讨论](http://chat.stackoverflow.com/rooms/7103/discussion-between-brianthelion-and-wazzzy) – BrianTheLion 2012-01-27 16:22:24

1

我花了一个小时才弄清楚,默认情况下,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 -