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

如何用Python 3.10的MoviePy实现不改变分辨率的视频放大?或OpenCV方案?

解决方案:视频内容放大但保持原分辨率

一、基于MoviePy的实现

MoviePy的resize方法会直接修改视频分辨率,要实现内容放大但输出分辨率不变,核心是先放大单帧内容,再裁剪回原分辨率(模拟镜头拉近的效果)。利用fl_image方法逐帧处理:

from moviepy.editor import VideoFileClip
import cv2

def process_zoom(frame, scale_factor):
    h, w = frame.shape[:2]
    # 放大当前帧
    zoomed_frame = cv2.resize(frame, (int(w * scale_factor), int(h * scale_factor)))
    # 计算裁剪区域,取放大后帧的中间部分,匹配原分辨率
    new_h, new_w = zoomed_frame.shape[:2]
    start_x = (new_w - w) // 2
    start_y = (new_h - h) // 2
    # 裁剪回原分辨率尺寸
    cropped_frame = zoomed_frame[start_y:start_y+h, start_x:start_x+w]
    return cropped_frame

# 加载输入视频
input_clip = VideoFileClip("input.mp4")
# 应用放大处理,这里设置放大倍数为2
zoomed_clip = input_clip.fl_image(lambda f: process_zoom(f, 2))
# 保存输出视频,保持原分辨率参数
zoomed_clip.write_videofile("output_moviepy.mp4", codec="libx264")

如果需要放大后保留完整内容、周围补黑边(而非裁剪局部),可以修改process_zoom函数,创建原分辨率的黑色画布,将放大后的帧居中放置:

import numpy as np

def process_zoom_with_pad(frame, scale_factor):
    h, w = frame.shape[:2]
    zoomed_frame = cv2.resize(frame, (int(w * scale_factor), int(h * scale_factor)))
    new_h, new_w = zoomed_frame.shape[:2]
    # 创建原分辨率的黑色画布
    padded_frame = np.zeros((h, w, 3), dtype=np.uint8)
    # 计算居中放置的坐标
    x_offset = (w - new_w) // 2 if new_w < w else 0
    y_offset = (h - new_h) // 2 if new_h < h else 0
    # 将放大后的帧放入画布
    padded_frame[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = zoomed_frame
    return padded_frame

二、基于OpenCV的实现

OpenCV通过逐帧读取-处理-写入的流程,直接实现内容放大且保持原分辨率:

import cv2

# 打开输入视频
cap = cv2.VideoCapture("input.mp4")
# 获取原视频的核心参数
orig_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
orig_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*"mp4v")

# 创建输出视频写入器,严格匹配原分辨率
out = cv2.VideoWriter("output_opencv.mp4", fourcc, fps, (orig_width, orig_height))

scale_factor = 2  # 设置放大倍数

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    # 放大帧内容
    zoomed_frame = cv2.resize(frame, (int(orig_width * scale_factor), int(orig_height * scale_factor)))
    # 裁剪中间区域,回到原分辨率
    new_h, new_w = zoomed_frame.shape[:2]
    x_start = (new_w - orig_width) // 2
    y_start = (new_h - orig_height) // 2
    cropped_frame = zoomed_frame[y_start:y_start+orig_height, x_start:x_start+orig_width]
    # 写入输出视频
    out.write(cropped_frame)

# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:42:53