【问题标题】:how to make a video from extracted frames?如何从提取的帧中制作视频?
【发布时间】:2020-09-17 17:52:21
【问题描述】:

我将视频帧提取到一个名为“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()

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

【问题讨论】:

  • 按照你写的顺序阅读它们

标签: python image opencv video frame


【解决方案1】:
  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))

【讨论】:

    【解决方案2】:

    如果您的要求需要您存储框架,试试这个

    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,输出的视频无法播放,能否解决一下?
    【解决方案3】:

    也许您可以尝试而不是保存图像并再次加载它们,从源视频中捕获视频并将其传递给输出对象(在本例中为 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()
    

    【讨论】:

    • 它不起作用,甚至不播放输出视频。
    • 刚刚做了一些更改,以写入与原始源视频相同宽度和高度的输出视频
    • 我想你误会了,我的文件夹中有图像,我想用它们制作视频,我希望我的视频是连续的,因为我的图像“或图像名称”是按顺序。
    • 在我编写的代码中(在 UPDATE 部分之后),我逐帧创建了具有唯一 ID(由 count 变量给出)的 .jpg 图像。之后,我使用 lista = [[x[5:-4],x] for x in os.listdir() if x.endswith('jpg')] 来读回它们( X[5:-4] 取决于如何命名您的当前目录/路径)。然后我使用 .sort 对列表进行排序,然后将它们放回视频中。我不知道您的图像名称是什么,所以这就是为什么我使用计数变量进行上一步保存它们的原因。如果这对您不起作用,您能否指定图像的名称类型。谢谢!
    【解决方案4】:

    尝试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() 没有对它们进行排序,我仍然在视频中得到一些随机图像。
    • 保存的图片的名称是什么。
    【解决方案5】:

    看来你需要自然排序,所以试试natsort library:

    from natsort import natsorted
    
    images = natsorted(images)
    

    使用 pip 安装:

    pip install natsort
    

    【讨论】:

      【解决方案6】:

      这很适合我

      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()
      

      材料和结果Here

      【讨论】:

        猜你喜欢
        • 2016-12-21
        • 1970-01-01
        • 2020-09-17
        • 2014-02-27
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多