jla*_*sch 5 python video opencv ffmpeg
如何将openCV图像传输到ffmpeg(作为子进程运行ffmpeg)?(我正在使用spyder/anaconda)
我正在从视频文件中读取帧并在每个帧上进行一些处理.
import cv2
cap = cv2.VideoCapture(self.avi_path)
img = cap.read()
gray = cv2.cvtColor(img[1], cv2.COLOR_BGR2GRAY)
bgDiv=gray/vidMed #background division
Run Code Online (Sandbox Code Playgroud)
然后,为了将处理过的帧传递给ffmpeg,我在一个相关问题中找到了这个命令:
sys.stdout.write( bgDiv.tostring() )
Run Code Online (Sandbox Code Playgroud)
接下来,我试图将ffmpeg作为子进程运行:
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)
Run Code Online (Sandbox Code Playgroud)
(这也来自上面提到的帖子)然而,这填充了我的IPython控制台与神秘的象形文字然后崩溃它.任何建议?
最终,我想输出4个流并让ffmpeg并行编码这4个流.
我有过类似的问题一次.我在Github上打开了一个问题,原来这可能是一个平台问题.
与您的问题相关,您也可以将OpenCV图像传输到FFMPEG.这是一个示例代码:
# 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()
Run Code Online (Sandbox Code Playgroud)
我有点晚了,但是我强大的VidGear Python 库可以通过其WriteGear API 的压缩模式,在任何平台上自动将 OpenCV 帧管道化到 FFmpeg 中。OP,您可以按如下方式实现您的答案:
# import libraries
from vidgear.gears import WriteGear
import cv2
output_params = {"-s":"2048x2048", "-r":30} #define 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
Run Code Online (Sandbox Code Playgroud)
您可以查看VidGear 文档以了解更多高级应用程序和功能。
希望有帮助!