使用 opencv 编写视频但输出文件无法播放
Video Writing using opencv but output file is not playable
我想并排使用两个视频编写一个视频文件,但最后输出文件无法在任何视频播放器中播放。
这是我的代码:
from __future__ import print_function
import numpy as np
import argparse
import cv2
import tkinter as tk
from tkinter import filedialog
import os
import os.path
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", type=str, default="sample.avi",
help="path to output video file")
ap.add_argument("-f", "--fps", type=int, default=100.0,
help="FPS of output video")
ap.add_argument("-c", "--codec", type=str, default="MJPG",
help="codec of output video")
args = vars(ap.parse_args())
root = tk.Tk()
root.withdraw()
source_video = filedialog.askopenfilename(title="Select file")
sign = filedialog.askopenfilename(title="Select file")
print("[INFO] Capturing video...")
cap1 = cv2.VideoCapture(source_video)
cap2 = cv2.VideoCapture(sign)
fourcc = cv2.VideoWriter_fourcc(*args["codec"])
writer = None
(h, w) = (None, None)
zeros = None
i = 0
try:
while cap1.isOpened():
ret, frame1 = cap1.read()
if ret:
frame1 = cv2.resize(frame1, (0, 0), fx=0.5, fy=0.5)
(h, w) = frame1.shape[:2]
ret, frame2 = cap2.read()
if ret:
frame2 = cv2.resize(frame2, (w, h))
else:
break
if writer is None:
writer = cv2.VideoWriter(args["output"], fourcc, args["fps"],
(h, w*2), True)
zeros = np.zeros((h, w*2), dtype="uint8")
output = np.zeros((h, w*2, 3), dtype="uint8")
if frame2 is None:
output[0:h, 0:w] = frame1
writer.write(output)
else:
output[0:h, 0:w] = frame1
output[0:h, w:w * 2] = frame2
writer.write(output)
cv2.imshow('output', output)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
writer.release()
cv2.destroyAllWindows()
except Exception as e:
print(str(e))
我没有收到任何错误,一切进展顺利,但是当我尝试播放目录中的输出视频文件时,它无法播放。我还检查了大约 16KB 的文件大小。我不知道问题出在哪里。请帮我。
我在用着:
Windows10 个 64 位
Python3.7
Pycharm 作为 IDE
VideoWriter
的 frameSize
参数是 (width, height),这在文档中有些隐藏(例如 here)。所以在你的代码中,它应该是
writer = cv2.VideoWriter(args["output"], fourcc, args["fps"], (w*2, h), True)
此修复后,您的代码为我制作了工作视频。
我注意到您的代码 "learns" 输入视频的帧大小而不是帧速率,但我认为这是故意的。
** 已解决 **
当您的相机生成的视频大小与您尝试创建的文件的视频大小不同时,就会出现此问题。
例如:我的 IP 摄像机生成大小为 (1920,1080) 的帧,在教程中我找到了他们试图编写大小为 (640,480) 的文件的代码。
我解决这个问题的方法是从摄像机中获取宽度和高度并将它们放入 videoWriter 方法中。
这里有适用于任何大小视频的代码:
import cv2
# desde la vídeo cámara: indicar ruta IP del stream
# desde file, indicar ruta de archivo
# desde cámara web: usar el número 0,1 ó -1
cap = cv2.VideoCapture('rtsp://admin:multisync1@192.168.0.64:554/Streaming/Channels/1')
# fourcc es el código del tipo de vídeo XVID = MPEG4
fourcc = cv2.VideoWriter_fourcc(*'XVID')
print("vídeo operativo: ",cap.isOpened())
videoWidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
videoHeight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print("ancho: ",videoWidth)
print("altura: ",videoHeight)
# 20= frames x segundo, (640x480) = tamaño del vídeo que grabaremos
# el tamaño del vídeo que se grabará debe ser igual al capturado de la cámara
out = cv2.VideoWriter('output_file.avi',fourcc, 20.0,(videoWidth,videoHeight))
while(cap.isOpened()): # si el file no existe, o no hay vídeo de la fuente indicada, dará False
# en este bucle se captura el vídeo frame por frame (cuadro por cuadro)
ret,frame = cap.read() # "ret" puede ser t/f dependiendo si se captura vídeo o no, "frame" contendrá el vídeo
if ret == True:
out.write(frame) # escribir en el file
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # convertir a gris el vídeo
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
我想并排使用两个视频编写一个视频文件,但最后输出文件无法在任何视频播放器中播放。 这是我的代码:
from __future__ import print_function
import numpy as np
import argparse
import cv2
import tkinter as tk
from tkinter import filedialog
import os
import os.path
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", type=str, default="sample.avi",
help="path to output video file")
ap.add_argument("-f", "--fps", type=int, default=100.0,
help="FPS of output video")
ap.add_argument("-c", "--codec", type=str, default="MJPG",
help="codec of output video")
args = vars(ap.parse_args())
root = tk.Tk()
root.withdraw()
source_video = filedialog.askopenfilename(title="Select file")
sign = filedialog.askopenfilename(title="Select file")
print("[INFO] Capturing video...")
cap1 = cv2.VideoCapture(source_video)
cap2 = cv2.VideoCapture(sign)
fourcc = cv2.VideoWriter_fourcc(*args["codec"])
writer = None
(h, w) = (None, None)
zeros = None
i = 0
try:
while cap1.isOpened():
ret, frame1 = cap1.read()
if ret:
frame1 = cv2.resize(frame1, (0, 0), fx=0.5, fy=0.5)
(h, w) = frame1.shape[:2]
ret, frame2 = cap2.read()
if ret:
frame2 = cv2.resize(frame2, (w, h))
else:
break
if writer is None:
writer = cv2.VideoWriter(args["output"], fourcc, args["fps"],
(h, w*2), True)
zeros = np.zeros((h, w*2), dtype="uint8")
output = np.zeros((h, w*2, 3), dtype="uint8")
if frame2 is None:
output[0:h, 0:w] = frame1
writer.write(output)
else:
output[0:h, 0:w] = frame1
output[0:h, w:w * 2] = frame2
writer.write(output)
cv2.imshow('output', output)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
writer.release()
cv2.destroyAllWindows()
except Exception as e:
print(str(e))
我没有收到任何错误,一切进展顺利,但是当我尝试播放目录中的输出视频文件时,它无法播放。我还检查了大约 16KB 的文件大小。我不知道问题出在哪里。请帮我。 我在用着: Windows10 个 64 位 Python3.7 Pycharm 作为 IDE
VideoWriter
的 frameSize
参数是 (width, height),这在文档中有些隐藏(例如 here)。所以在你的代码中,它应该是
writer = cv2.VideoWriter(args["output"], fourcc, args["fps"], (w*2, h), True)
此修复后,您的代码为我制作了工作视频。
我注意到您的代码 "learns" 输入视频的帧大小而不是帧速率,但我认为这是故意的。
** 已解决 ** 当您的相机生成的视频大小与您尝试创建的文件的视频大小不同时,就会出现此问题。
例如:我的 IP 摄像机生成大小为 (1920,1080) 的帧,在教程中我找到了他们试图编写大小为 (640,480) 的文件的代码。
我解决这个问题的方法是从摄像机中获取宽度和高度并将它们放入 videoWriter 方法中。
这里有适用于任何大小视频的代码:
import cv2
# desde la vídeo cámara: indicar ruta IP del stream
# desde file, indicar ruta de archivo
# desde cámara web: usar el número 0,1 ó -1
cap = cv2.VideoCapture('rtsp://admin:multisync1@192.168.0.64:554/Streaming/Channels/1')
# fourcc es el código del tipo de vídeo XVID = MPEG4
fourcc = cv2.VideoWriter_fourcc(*'XVID')
print("vídeo operativo: ",cap.isOpened())
videoWidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
videoHeight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print("ancho: ",videoWidth)
print("altura: ",videoHeight)
# 20= frames x segundo, (640x480) = tamaño del vídeo que grabaremos
# el tamaño del vídeo que se grabará debe ser igual al capturado de la cámara
out = cv2.VideoWriter('output_file.avi',fourcc, 20.0,(videoWidth,videoHeight))
while(cap.isOpened()): # si el file no existe, o no hay vídeo de la fuente indicada, dará False
# en este bucle se captura el vídeo frame por frame (cuadro por cuadro)
ret,frame = cap.read() # "ret" puede ser t/f dependiendo si se captura vídeo o no, "frame" contendrá el vídeo
if ret == True:
out.write(frame) # escribir en el file
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # convertir a gris el vídeo
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()