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

OpenCV生成全景图平移视频时触发段错误求助

OpenCV 4.6.0 + Python 在Linux 22.04下生成全景平移视频段错误的解决思路

问题描述

在Linux 22.04系统中,使用OpenCV 4.6.0与Python开发全景图平移视频时,前100帧生成正常,后续触发段错误。裁剪后的帧导出为JPG无异常,更换源图格式(PNG/JPG)、多种编码器均无法解决问题。相关代码如下:

import numpy as np
import cv2

imgPath = './../pan/pan_01/pan_01_B_small.png'
width=1920
height=1080
chan=3
fps=30
seconds=10
numframes = fps*seconds

img = cv2.imread(imgPath, 1)
print("Image Size:", img.shape)
shiftPerFrame = (img.shape[1] - width) / numframes
print(img.shape[1])
print("Shift/Frame: ", shiftPerFrame)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, fps, (width,height))

for i in range(1,numframes):   # init frames
    x = int(i * shiftPerFrame)
    crop_img = img[0:height, x:x+width]
    print("Frame: ", i, " Position x:", x, " to ", x+width, "size: ", crop_img.shape)
    out.write(crop_img)
    #cv2.imwrite("data/img" + str(i) + ".jpg", crop_img)
    
out.release()

可能原因与解决步骤

1. 修复浮点累计偏移的边界越界问题

shiftPerFrame为浮点数,循环中int(i * shiftPerFrame)会产生累计误差,后期可能导致x+width超过图片实际宽度,触发内存越界。

解决代码:

total_shift = img.shape[1] - width
# 用linspace生成无累计误差的整数偏移序列
x_positions = np.linspace(0, total_shift, numframes, endpoint=False, dtype=np.int32)

for i in range(numframes):
    x = x_positions[i]
    # 强制裁剪范围不越界
    crop_img = img[0:min(height, img.shape[0]), x:x+width]
    # 确保尺寸与VideoWriter一致
    if crop_img.shape[0] < height:
        crop_img = cv2.copyMakeBorder(crop_img, 0, height - crop_img.shape[0], 0, 0, cv2.BORDER_CONSTANT)
    out.write(crop_img)

2. 强制帧格式与编码器参数匹配

部分编码器对帧格式的兼容性要求严格,显式指定颜色空间与格式:

修改代码:

# 更换为更稳定的MP4编码器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 显式指定isColor参数,避免自动检测错误
out = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height), isColor=True)

# 裁剪后强制转换为uint8格式
crop_img = img[0:height, x:x+width].astype(np.uint8)

3. 升级OpenCV版本

OpenCV 4.6.0存在部分内存管理与编码器的已知bug,升级至4.8.0及以上版本可修复:

pip install --upgrade opencv-python

4. 添加调试与异常捕获

定位具体出错帧的边界情况,排查内存访问问题:

for i in range(numframes):
    try:
        x = x_positions[i]
        crop_img = img[0:height, x:x+width]
        if crop_img.shape != (height, width, chan):
            print(f"Frame {i}: 尺寸不匹配 {crop_img.shape}")
            continue
        out.write(crop_img)
    except Exception as e:
        print(f"Frame {i} 出错: {str(e)}, x={x}, 图片宽度={img.shape[1]}")
        break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:07:35