【问题标题】:PIL Image list into a video slide with cv2.VideoWriter使用 cv2.VideoWriter 将 PIL 图像列表转换为视频幻灯片
【发布时间】:2021-02-06 21:16:51
【问题描述】:

我创建了关注函数。

import cv2
import numpy as np

FPS = 10

def write_video(file_name, images, slide_time=5):
    fourcc = cv2.VideoWriter.fourcc(*'X264')
    out = cv2.VideoWriter(file_name, fourcc, FPS, (870, 580))

    for image in images:
        cv_img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
        for _ in range(slide_time * FPS):
            out.write(cv_img)

    out.release()

它曾经工作过,但我打破了它,不知道如何。

当我尝试使用 MPV 打开时,我得到:

[ffmpeg/demuxer] avi: Could not find codec parameters for stream 0 (Video: h264 (X264 / 0x34363258), none, 870x580): unspecified pixel format
[ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' and 'probesize' options
 (+) Video --vid=1 (h264 870x580 10.000fps)


Exiting... (Errors when loading file)

这是一个最小的可重现示例:

import requests
from PIL import Image
from io import BytesIO
import cv2
import numpy as np



FPS = 10

res = requests.get('https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.bNvIoWPYwYWXe-gpRKsalQHaE9%26pid%3DApi&f=1')

image = Image.open(BytesIO(res.content))
image = np.array(image)
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

fourcc = cv2.VideoWriter.fourcc(*'MJPG')
video = cv2.VideoWriter('output.avi', fourcc, FPS, (870, 580))


for _ in range(13 * FPS):
    video.write(image)

video.release()

【问题讨论】:

    标签: python opencv python-imaging-library cv2


    【解决方案1】:

    我想解决您的代码的问题。

    • 问题#1:

    • 错误提示:

      找不到流 0 的编解码器参数(视频:h264"

      • 表示x264 编解码器在您当前的环境中不可用。

      • 你要么安装opencv-python要么

      • 将编解码器初始化为MJPG (Motion-JPEG)。原因是MJPG 适合.avi 文件。

      • fourcc = cv2.VideoWriter.fourcc(*'MJPG')
        
    • 问题#2:


    • 您正在从 RGB 转换为 BGR

    • 我建议阅读图片,因此您不必转换为BGR

    • cv2.imread 读取BGR 格式的图像

    • 还要确保每个图像的大小与定义的VideoCapture 大小相同。

      • for image in images:
            cv_img = cv2.imread(image)
            cv_img = cv2.resize(cv_img, (870, 580))
        

    根据最小可重现错误更新代码:


    import cv2
    from glob import glob
    
    FPS = 10
    
    
    def write_video(file_name, images, slide_time=5):
        fourcc = cv2.VideoWriter.fourcc(*'MJPG')
        out = cv2.VideoWriter(file_name, fourcc, FPS, (870, 580))
    
        for image in images:
            cv_img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
            for _ in range(slide_time * FPS):
                cv_img = cv2.resize(image, (870, 580))
                out.write(cv_img)
    
        out.release()
    
    
    if __name__ == '__main__':
        write_video(file_name='result.avi', images=glob("b/*.jpg"))
    

    【讨论】:

    • 图像是 PIL 图像实例。我不想将图像保存到磁盘中。我以前用 MJPG 试过,又试了一次,同样的错误。它以前工作过一次,不知道我改变了什么,现在它不再工作了。
    • 如果它们是 PIL 图像实例,为什么不使用 cv_img = Image.open(image)?我的意思是,您必须使用Image.opencv2.imread 读取图像。否则,您将图像路径作为参数传递。
    • 不,图片是来自请求的响应。我将响应内容放入 BytesIO 并用 PIL 打开它。 Image.open(BytesIO(response.content))
    • 我很困惑,Image.open(BytesIO(response.content))for image in images: 的关系如何。所以每个image 不是像C:..\\..\\MyPic\\...\\.png 这样的路径?
    • 是的,就是这样。我从 get 响应中读取了创建 Image 实例。就像从文件中打开的图像一样,我可以调用 .show() 它以相同的方式显示。 images 是一个 PIL Image 数组。
    猜你喜欢
    • 2017-10-11
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多