将列表中附加的帧写入 OpenCV 中的视频

Writing frames appended in a list onto a video in OpenCV

下面的代码读取视频并将其逐帧存储到列表中。这样做的原因是因为我可能希望将视频中的单个帧用于其他目的,例如模糊或转换为二进制图像。然后我想将这些处理过的帧转换成视频。我对 OpenCV 的理解使我编写了下面的代码,但这给了我一个 Expected Ptr<cv::UMat> for argument 'src' 错误。为什么会这样?

import cv2
vidcap = cv2.VideoCapture("ThisVid.wmv")

#store every frame from video file 
success,image = vidcap.read()
count = 0
success = True
frames = []
while success:
    frames.append(image)
    success,image = vidcap.read()
    count += 1

vidcap.release()

newframes = [] 

for i in range(0,len(frames),100):
    newframes.append(frames[i])
    
writer = cv2.VideoWriter("outputvideo.mp4",cv2.VideoWriter_fourcc(*"MP4V"),30,(512,512))
writer.write(cv2.resize(newframes,(512,512))) #write frame into output vid
writer.release()

cv2.resize 需要 个人 图像。您提供的图像列表不符合预期的签名。此外,cv2.VideoWriter.write 一次只写入一帧,而您提供的是帧列表。因此,在使用 newframes 的循环中,甚至不要使用新列表。在循环中调整帧大小,然后写入磁盘。

writer = cv2.VideoWriter("outputvideo.mp4",cv2.VideoWriter_fourcc(*"MP4V"),30,(512,512))
for i in range(0,len(frames),100):
    resiz = cv2.resize(frames[i], (512, 512))
    writer.write(resiz)
writer.release()

我想提个建议:

success = True
frames = []
while success:

与其像上面这样写,不如这样写:

frames = []
while vidcap.isOpened():

上面的代码是有道理的。如果视频已打开,则处理其帧。

我的第二个建议是:

frames.append(image)
success,image = vidcap.read()
count += 1

首先检查 frame 是否返回,然后追加到列表中。

while vid_cap.isOpened():
    success, image = vid_cap.read()
    if success:
        frames.append(image)
        count += 1

您将 VideWriter 初始化为:

writer = cv2.VideoWriter("outputvideo.mp4", cv2.VideoWriter_fourcc(*"MP4V"), 30, (512, 512))

有两个约束:


1- 每帧必须是 (512, 512) 大小

2-而且每帧必须是rgb。

如果你想要灰度视频,你需要将isColor变量设置为False

writer = cv2.VideoWriter("outputvideo.mp4", cv2.VideoWriter_fourcc(*"MP4V"), 30, (512, 512), isColor=False)

因为你想要每个帧大小 (512, 512) 你可以这样做:img = cv2.resize(image, (512, 512))

while vid_cap.isOpened():
    success, image = vid_cap.read()
    if success:
        img = cv2.resize(image, (512, 512))
        frames.append(img)
        count += 1
    else:
        break

现在,Expected Ptr<cv::UMat> for argument 'src' 意味着 writer.write 第一个参数 image 应该是一个框架,但你给出了一个列表输入。因此:

1- 初始化 VideoWriter 对象

2- 使用“mp4v”代替“MP4V”,否则您可能会收到警告

2- 使用 for-loop

写入帧
writer = cv2.VideoWriter("outputvideo.mp4", cv2.VideoWriter_fourcc(*"mp4v"), 30, (512, 512))

for i in range(0, len(frames), 100):
    newframes.append(frames[i])
    writer.write(frames[i])

writer.release()

代码:


import cv2

vid_cap = cv2.VideoCapture("result.mp4")

# store every frame from video file
success, image = vid_cap.read()
count = 0
frames = []

while vid_cap.isOpened():
    success, image = vid_cap.read()
    if success:
        img = cv2.resize(image, (512, 512))
        frames.append(img)
        count += 1
    else:
        break

vid_cap.release()

newframes = []

writer = cv2.VideoWriter("outputvideo.mp4", cv2.VideoWriter_fourcc(*"mp4v"), 30, (512, 512))

for i in range(0, len(frames), 100):
    newframes.append(frames[i])
    writer.write(frames[i])  # write frame into output vid

writer.release()