You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenCV和Python处理不同尺寸图片与视频的互转?

异尺寸图片集与视频互转方案(保留原图片尺寸)

一、生成兼容异尺寸图片的视频

OpenCV的VideoWriter要求视频帧尺寸固定,直接写入不同尺寸图片会触发尺寸不匹配错误。解决思路:

  • 遍历所有图片,取最大宽高作为视频帧固定尺寸,确保所有原始图片能完整放入画布
  • 将每张图片放置在黑色画布左上角(无任何缩放),保留原始像素信息
  • 同步保存元数据文件,记录每一帧对应的原始图片尺寸和文件名,为后续提取做准备

实现代码

import cv2
import json
import os
import numpy as np

def images_to_video(image_list, output_video, fps=1):
    # 遍历图片获取最大宽高,筛选有效图片
    max_width = 0
    max_height = 0
    valid_images = []
    for img_path in image_list:
        img = cv2.imread(img_path)
        if img is None:
            print(f"警告:跳过无法读取的图片 {img_path}")
            continue
        h, w = img.shape[:2]
        max_width = max(max_width, w)
        max_height = max(max_height, h)
        valid_images.append(img_path)
    
    if not valid_images:
        raise ValueError("没有可处理的有效图片")
    
    # 初始化视频写入器
    codec = cv2.VideoWriter_fourcc(*"mp4v")
    video_writer = cv2.VideoWriter(output_video, codec, fps, (max_width, max_height))
    
    # 写入视频并记录元数据
    metadata = []
    for img_path in valid_images:
        img = cv2.imread(img_path)
        h, w = img.shape[:2]
        # 创建与最大尺寸一致的黑色画布
        canvas = np.zeros((max_height, max_width, 3), dtype=np.uint8)
        # 将原始图片放置在画布左上角(无缩放)
        canvas[:h, :w] = img
        video_writer.write(canvas)
        # 记录元数据:文件名、原始宽高
        metadata.append({
            "filename": os.path.basename(img_path),
            "original_width": w,
            "original_height": h
        })
    
    video_writer.release()
    # 保存元数据到JSON文件
    metadata_file = f"{os.path.splitext(output_video)[0]}_metadata.json"
    with open(metadata_file, "w") as f:
        json.dump(metadata, f, indent=2)
    
    print(f"视频生成完成:{output_video}")
    print(f"元数据文件已保存:{metadata_file}")

# 示例调用
image_list = ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg"]
images_to_video(image_list, "output.mp4", fps=1)

二、从视频提取原尺寸图片

借助生成视频时保存的元数据,从每一帧对应区域裁剪出原始尺寸的图片,完全保留原始像素,无缩放或变形。

实现代码

import cv2
import json
import os

def video_to_images(input_video, output_dir="extracted_images"):
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 读取元数据文件
    metadata_file = f"{os.path.splitext(input_video)[0]}_metadata.json"
    if not os.path.exists(metadata_file):
        raise FileNotFoundError(f"未找到对应元数据文件:{metadata_file}")
    
    with open(metadata_file, "r") as f:
        metadata = json.load(f)
    
    # 读取视频
    cap = cv2.VideoCapture(input_video)
    if not cap.isOpened():
        raise ValueError(f"无法打开视频文件:{input_video}")
    
    frame_idx = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        
        if frame_idx >= len(metadata):
            print(f"警告:视频帧数({frame_idx+1})多于元数据记录数({len(metadata)}),跳过后续帧")
            break
        
        # 获取当前帧对应的原始图片信息
        img_info = metadata[frame_idx]
        orig_w, orig_h = img_info["original_width"], img_info["original_height"]
        # 裁剪出原始尺寸区域(左上角)
        original_img = frame[:orig_h, :orig_w]
        # 保存图片
        output_path = os.path.join(output_dir, img_info["filename"])
        cv2.imwrite(output_path, original_img)
        print(f"已保存:{output_path}")
        
        frame_idx += 1
    
    cap.release()
    print(f"图片提取完成,所有文件保存至:{output_dir}")

# 示例调用
video_to_images("output.mp4")

核心优势

  • 完全保留原始图片的尺寸和像素信息,提取后的图片与上传时完全一致
  • 解决了异尺寸图片生成视频的尺寸不匹配问题
  • 元数据文件轻量易读取,确保提取过程的准确性

内容的提问来源于stack exchange,提问作者Gevin Hasmitha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:55:08