2011-04-28 40 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 -