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

PyInstaller打包Kivy+OpenCV视频灰度工具遇递归深度超限错误求助

问题:PyInstaller打包Kivy+OpenCV视频灰度转换应用出现递归深度超限错误

问题背景

  • 开发基于Kivy和OpenCV的桌面应用,实现视频转灰度功能
  • 开发环境中运行正常,但使用以下PyInstaller命令打包后报错:

Failed to execute script 'main' due to unhandled exception: maximum recursion depth exceeded

  • 打包命令:pyinstaller --name VideoCartoonizer --windowed --onefile main.py

错误日志

File "logging\__init__.py", line 1084, in emit
AttributeError: 'NoneType' object has no attribute 'write'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "logging\__init__.py", line 1084, in emit
AttributeError: 'NoneType' object has no attribute 'write'

...(重复错误栈省略)

RecursionError: maximum recursion depth exceeded

问题根源分析

  1. 视频处理逻辑严重错误:原代码中循环用concatenate_videoclips拼接新生成的VideoClip,会创建嵌套层级极深的剪辑对象,最终触发递归深度超限。同时VideoClip的lambda参数完全不符合MoviePy的帧生成规则——该函数应接收时间t并返回对应帧,而非直接弹出队列元素。
  2. 窗口模式日志异常:--windowed模式下Kivy日志无法输出到控制台,引发AttributeError,后续错误处理的连锁反应触发递归错误。

修复方案

1. 重构核心视频处理逻辑

替换原convert_video方法,使用MoviePy标准的帧处理方式:

def convert_video(self, *args):
    # 获取输入文件路径
    input_file = self.input_file.text
    if not input_file:
        return

    # 定义帧处理函数:MoviePy帧为RGB格式,需适配OpenCV
    def process_frame(frame):
        # 按比例调整帧大小
        aspect_ratio = frame.shape[1] / frame.shape[0]
        target_width = 640
        target_height = int(target_width / aspect_ratio)
        resized_frame = cv2.resize(frame, (target_width, target_height))
        
        # RGB转BGR(OpenCV格式)→ 转灰度 → 转回RGB(适配MoviePy)
        gray_bgr = cv2.cvtColor(resized_frame, cv2.COLOR_RGB2GRAY)
        gray_rgb = cv2.cvtColor(gray_bgr, cv2.COLOR_GRAY2RGB)
        return gray_rgb

    # 生成输出路径并处理视频
    output_file = input_file.replace(".mp4", "_cartoon.mp4")
    self.output_file.text = output_file

    with VideoFileClip(input_file) as input_video:
        # 使用fl_image批量处理所有帧,MoviePy标准用法
        output_video = input_video.fl_image(process_frame)
        # 写入输出视频
        output_video.write_videofile(output_file, codec='mpeg4')

2. 解决窗口模式日志问题

在代码开头添加日志配置,避免无控制台时的输出错误:

import logging
from logging.handlers import NullHandler

# 配置空日志处理器,防止窗口模式下日志报错
logging.basicConfig(handlers=[NullHandler()], level=logging.INFO)

3. 优化PyInstaller打包命令

添加Kivy和MoviePy的必要依赖声明,确保打包完整:

pyinstaller --name VideoCartoonizer --windowed --onefile --hidden-import=kivy.deps.sdl2 --hidden-import=kivy.deps.glew --hidden-import=moviepy.video.fx.all --hidden-import=moviepy.audio.fx.all main.py

关键注意事项

  • MoviePy的fl_image是批量处理视频帧的标准方式,无需手动循环拼接剪辑
  • MoviePy帧格式为RGB,OpenCV默认是BGR,转换时必须做通道适配
  • 灰度帧需转回3通道RGB,否则MoviePy写入视频时会格式报错
  • 打包时必须显式声明Kivy的底层依赖和MoviePy的特效模块,避免缺失依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:44:57