如何从提取的帧制作视频?

5

我将视频帧提取到名为“images”的文件夹中。在将图像保存到文件夹后,我使用以下代码重新创建视频。我得到了视频,但是帧的顺序是随机的,如何将它们按顺序排列?感谢这篇文章。

import cv2
import os


image_folder = 'images'
video_name = 'video.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))

cv2.destroyAllWindows()
video.release()

请指教,我该如何解决这个问题?我希望视频的速率与原始视频相同,并且帧按顺序排列。


1
按照写作顺序阅读它们 - Yunus Temurlenk
6个回答

3
  1. 打印你的images列表并查看图片的顺序,它们是否已排序?
  2. 你的图片文件名是什么?选择一个逐渐增加的数字作为文件名,例如00001.jpg00002.jpg而不是1.jpg2.jpg,这可以避免排序混乱。

    1. os.listdir('.')中读取后对图片进行排序: 这是一个使用pathlib库的示例。
for filename in sorted([e for e in path.iterdir() if e.is_file() and str(e).endswith(".png")]):
    print(filename)
    img = cv2.imread(str(filename))
    img_array.append(img)

或者仅使用以下代码:

for filename in sorted(os.listdir(path))

0
也许你可以尝试不是保存图像并再次加载它们,而是从源视频中进行视频捕获,并将其传递给输出对象(在这种情况下为demo_output.avi)...就像这样:
import cv2

cap = cv2.VideoCapture('path to video/video.mp4')

fourcc = cv2.VideoWriter_fourcc(*'XVID')
ret, frame = cap.read()
fps_video=cap.get(cv2.CAP_PROP_FPS)
height,width = frame.shape[:2]
out = cv2.VideoWriter('demo_output.avi',fourcc, fps_video, (width,height)) ##can be set with your width,height values




while ret:
    frame = cv2.resize(frame, None, fx=1.0, fy=1.0, interpolation=cv2.INTER_AREA)

    out.write(frame)
    ret, frame = cap.read()

cap.release()
out.release()
cv2.destroyAllWindows()      

更新:

如果您想要图像并保存视频文件:

import cv2
import os
import numpy as np

vidcap = cv2.VideoCapture('path to video/video.mp4')
success,image = vidcap.read()
fps_video = vidcap.get(cv2.CAP_PROP_FPS)
height,width = image.shape[:2]
count = 0
while success:

    cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file      
    success,image = vidcap.read()
    print('Read a new frame: ', success)
    count += 1

vidcap.release()
lista = [[x[5:-4],x] for x in os.listdir() if x.endswith('jpg')]

result=[]
for x in lista:
    t1,t2 = np.int(x[0]),x[1]
    result.append([t1,t2])

result.sort()

#recording video back
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('demo_output.avi',fourcc, fps_video, (width,height)) ##can be set with your width,height values

for img in result:
    frame = cv2.imread(img[1])
    out.write(frame)
out.release()

它不起作用,甚至无法播放输出视频。 - nikki
刚刚进行了一些更改,以便将输出视频的宽度和高度与原始源视频相同。 - Raburgos
我觉得你误解了我的意思,我在文件夹中有图片,我想把它们制作成视频,我希望我的视频是按顺序的,因为我的图片名称是有序的。 - nikki
在我编写的代码中(UPDATE部分之后),我使用唯一ID(由计数变量给出)逐帧创建了.jpg图像。然后,我使用lista = [[x[5:-4],x] for x in os.listdir() if x.endswith('jpg')]将它们读回来(X[5:-4]取决于当前目录/路径的命名方式)。然后,我使用.sort对列表进行排序,并将它们放回视频中。我不知道你的图像名称是什么,所以我先使用计数变量保存它们。如果这对你不起作用,请指定你的图像名称是什么样的。谢谢! - Raburgos

0
如果您的需求需要存储帧,请尝试这个。
import cv2
import os


image_folder = 'images'
video_name = 'video.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for i in range(len(images)):
    video.write(cv2.imread(os.path.join(image_folder, 'a'+str(i)+'.jpg')))

cv2.destroyAllWindows()
video.release()

@soumuth,输出的视频无法播放,你能修复一下吗? - nikki

0
尝试使用glob列出文件并对列表进行排序。我已经使用glob编辑了您的代码。(假设您的图像文件名按照您想要的顺序排列)
import cv2
import os
import glob

video_name = 'video.avi'

images = glob.glob('images/*.jpg')
images.sort()

frame = cv2.imread(images[0])
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for image in images:
    video.write(cv2.imread(image))

cv2.destroyAllWindows()
video.release() 

images.sort()并没有对它们进行排序,我仍然在视频中得到一些随机的图像。 - nikki
图像保存的名称是什么? - Vardan Agarwal

0

看起来你需要自然排序,那么尝试使用natsort库:

from natsort import natsorted

images = natsorted(images)

使用pip进行安装:

pip install natsort

0

这对我来说运作良好

import cv2
import os


image_folder = 'c:\\m\\'
video_name = 'c:\\m\\avideo.avi'

images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")]


frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

#1 fps
#video = cv2.VideoWriter(video_name, 0, 1, (width,height))


#25 fps
video = cv2.VideoWriter(video_name, 0, 25, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))

cv2.destroyAllWindows()
video.release()

材料和结果 这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接