2015-12-08 13 views
5

Wie kann ich OpenCV Bilder zu ffmpeg (Ausführen von ffmpeg als Subprozess)? (ich benutze spyder/anaconda)Pipe opencv Bilder zu ffmpeg mit Python

Ich lese Frames aus einer Videodatei und mache einige Verarbeitung für jeden Frame.

import cv2 
cap = cv2.VideoCapture(self.avi_path) 
img = cap.read() 
gray = cv2.cvtColor(img[1], cv2.COLOR_BGR2GRAY) 
bgDiv=gray/vidMed #background division 

dann die verarbeiteten Rahmen zu ffmpeg Rohr, ich diesen Befehl in einer verwandten Frage gefunden:

sys.stdout.write(bgDiv.tostring()) 

nächstes versuche ich ffmpeg als subprocess auszuführen:

cmd='ffmpeg.exe -f rawvideo -pix_fmt gray -s 2048x2048 -r 30 -i - -an -f avi -r 30 foo.avi' 
sp.call(cmd,shell=True) 

(dies auch aus dem genannten Beitrag) Allerdings füllt dies meine IPython-Konsole mit kryptischen Hieroglyphen und stürzt dann ab. irgendein Rat?

letztlich würde ich gerne 4 Streams auspipsen und ffmpeg diese 4 Streams parallel kodieren.

+0

Gibt es einen Grund, warum Sie OpenCV VideoWriter-Schnittstelle nicht verwenden möchten, um Ihr Video zu schreiben? Ich glaube nicht, dass du 4 Streams auf einmal rausholen kannst. – mirosval

+0

Ich hatte gehofft, das wäre schneller zum Speichern des Videos. Ich habe bemerkt, dass mein openCV-Lese-Schreib-Beispiel oben mit VideoWriter etwa doppelt so lang war wie eine reine ffmpeg-Kodierung des gleichen Eingangsvideos (vorausgesetzt, die ffmpeg-Kodierung enthielt keine Hintergrundeinteilung - weshalb ich openCV probierte) den ersten Platz). Ich hoffte, Named Pipes zu verwenden ... – jlarsch

Antwort

8

Ich hatte ein ähnliches Problem einmal. I opened an issue on Github, stellt sich heraus kann ein Plattformproblem sein.

In Bezug auf Ihre Frage können Sie auch OpenCV-Bilder zu FFMPEG leiten. Hier ist ein Beispielcode:

# This script copies the video frame by frame 
import cv2 
import subprocess as sp 

input_file = 'input_file_name.mp4' 
output_file = 'output_file_name.mp4' 

cap = cv2.VideoCapture(input_file) 
ret, frame = cap.read() 
height, width, ch = frame.shape 

ffmpeg = 'FFMPEG' 
dimension = '{}x{}'.format(width, height) 
f_format = 'bgr24' # remember OpenCV uses bgr format 
fps = str(cap.get(cv2.CAP_PROP_FPS)) 

command = [ffmpeg, 
     '-y', 
     '-f', 'rawvideo', 
     '-vcodec','rawvideo', 
     '-s', dimension, 
     '-pix_fmt', 'bgr24', 
     '-r', fps, 
     '-i', '-', 
     '-an', 
     '-vcodec', 'mpeg4', 
     '-b:v', '5000k', 
     output_file ] 

proc = sp.Popen(command, stdin=sp.PIPE, stderr=sp.PIPE) 

while True: 
    ret, frame = cap.read() 
    if not ret: 
     break 
    proc.stdin.write(frame.tostring()) 

cap.release() 
proc.stdin.close() 
proc.stderr.close() 
proc.wait() 
+0

Ich erhalte einen Fehler: pipe.proc.stdin.write (frame.tostring()) AttributeError: 'Popen' Objekt hat kein Attribut 'proc – jlarsch

+0

Wenn ich Ihren Code ändern zu 'pipe.stdin.write (frame.tostring())', bekomme ich einen weiteren Fehler: 'pipe.stdin.write (frame.tostring()) IOError: [Errno 22] Ungültiges argumen' – jlarsch

+0

Dies ist Python 2.7-Code . Welche Version ist dein Python? –

Verwandte Themen