如何捕获 OpenCV 写入 stderr 的消息?

Posted

技术标签:

【中文标题】如何捕获 OpenCV 写入 stderr 的消息?【英文标题】:How to capture messages written to stderr by OpenCV? 【发布时间】:2022-01-12 12:16:36 【问题描述】:

如果参数无效,cv2.VideoWriter 会将内容写入 stderr。这是一个最小的例子:

import cv2

cv2.VideoWriter("foo.mp4", cv2.VideoWriter_fourcc(*"mp4v"), 90000, (240, 240))

这样跑

python3 video_verification/verification.py 2> err.txt

可以在err.txt 中看到预期的错误:

[mpeg4 @ 0x13e4640] timebase 1/90000 not supported by MPEG 4 standard, the maximum admitted value for the timebase denominator is 65535
[ERROR:0] global /tmp/pip-req-build-13uokl4r/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp (2705) open Could not open codec mpeg4, error: Unspecified error
[ERROR:0] global /tmp/pip-req-build-13uokl4r/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp (2722) open VIDEOIO/FFMPEG: Failed to initialize VideoWriter

但是,我无法直接在 Python 中捕获这一点。到目前为止,这是我的两次(失败)尝试:

import io
from contextlib import redirect_stdout, redirect_stderr

import cv2

f_out = io.StringIO()
f_err = io.StringIO()
with redirect_stdout(f_out):
    with redirect_stderr(f_err):
        fps = 90000
        writer = cv2.VideoWriter(
            "foo.mp4", cv2.VideoWriter_fourcc(*"mp4v"),
            fps, (240, 240)
        )

print(f"stdout: f_out.getvalue()")
print(f"stderr: f_err.getvalue()")
import io
import sys

import cv2


def flush():
    sys.stdout.flush()
    sys.stderr.flush()


flush()

original_stdout = sys.stdout
original_stderr = sys.stderr

captured_stdout = io.StringIO()
captured_stderr = io.StringIO()

sys.stdout = captured_stdout
sys.stderr = captured_stderr

flush()

cv2.VideoWriter("foo.mp4", cv2.VideoWriter_fourcc(*"mp4v"), 90000, (240, 240))

flush()

sys.stdout = original_stdout
sys.stderr = original_stderr

print(f"stdout: captured_stdout.getvalue()")
print(f"stderr: captured_stderr.getvalue()")

我很想知道我做错了什么。 :-)

【问题讨论】:

也许你可以适应这个...eli.thegreenplace.net/2015/… 【参考方案1】:

我找到了wurlitzer library,它可以做到这一点,即捕获由 C 库写入的流:

import cv2
from wurlitzer import pipes

with pipes() as (out, err):
    cv2.VideoWriter("foo.mp4", cv2.VideoWriter_fourcc(*"mp4v"), 90000, (240, 240))

print(f"stderr: err.read()")

【讨论】:

酷 - 感谢分享!

以上是关于如何捕获 OpenCV 写入 stderr 的消息?的主要内容,如果未能解决你的问题,请参考以下文章

当方法生成 std​​err 时,如何将信息添加到 STDERR?

如何使用 googletest 捕获标准输出/标准错误?

输出重定向是不是按顺序写入 stdout 和 stderr 信息?

利用OpenCV读取和写入视频

Qt OpenCV从捕获帧写入视频,不保存

如何关闭 libavformat 错误消息