如何停止在Python中打印OpenCV错误消息

2024-04-25 04:24:03 发布

您现在位置:Python中文网/ 问答频道 /正文

this question here相同,除了Python,而不是C++。在

除非我在打印简历时发现了错误。在

solution to the linked question建议使用重定向函数,但是this comment建议在Python for OpenCV中不存在该函数。在

如何停止打印OpenCV错误消息,同时仍允许打印出我想要的内容?在


Tags: theto函数消息forhere错误comment
1条回答
网友
1楼 · 发布于 2024-04-25 04:24:03

在编写这个答案时(opencv3.4.1是最新发布的版本),没有办法只过滤默认错误处理程序的输出(我能想到),也没有办法更改错误处理程序。在

但是,你的问题让我在highgui模块中思考了一下,我们已经有几个函数可以让我们为鼠标、轨迹条和按钮事件设置Python回调,因此我们可以从代码中获得灵感,并在中修补这个新功能。在

让我们使用版本3.4.1。感兴趣的文件是^{}。我们将从函数^{}^{}中获得灵感。在

让Python错误处理程序具有与C++ error handler匹配的签名:

error_handler([int]status, [str]func_name, [str]err_msg, [str]file_name, [int]line, [obj]userdata) -> None

让我们添加对默认错误处理程序重置的支持,highgui函数还没有做到这一点。在

首先,我们需要一个静态错误处理函数,它将从C++到python进行参数化,并调用适当的Python函数来处理错误。就像我们从中获得灵感的函数一样,我们将使用user data参数保存一个元组,该元组由一个function对象和可选的Python用户数据组成)。在

^{pr2}$

接下来,我们需要编写函数来实现Python和C++之间的绑定。但是,由于我的suspicions of potential memory leaks在我们从中得到启发的函数中,我们将添加一些内容来修复我们将跟踪最新的用户数据对象并在必要时取消引用它。在

^{3}$

最后,我们必须注册我们的"special method"。与我们从中获得灵感的函数不同,我们不依赖某些GUI,我们希望它始终可用,因此我们将修改代码,如下所示:

static PyMethodDef special_methods[] = {
  {"redirectError", (PyCFunction)pycvRedirectError, METH_VARARGS | METH_KEYWORDS, "redirectError(onError [, param]) -> None"},
#ifdef HAVE_OPENCV_HIGHGUI
  {"createTrackbar", pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
  {"createButton", (PyCFunction)pycvCreateButton, METH_VARARGS | METH_KEYWORDS, "createButton(buttonName, onChange [, userData, buttonType, initialButtonState]) -> None"},
  {"setMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_VARARGS | METH_KEYWORDS, "setMouseCallback(windowName, onMouse [, param]) -> None"},
#endif
  {NULL, NULL},
};

现在我们可以重建OpenCV,安装并测试它。我编写了以下脚本来演示该功能:

import cv2

def verbose_error_handler(status, func_name, err_msg, file_name, line, userdata):
    print "Status = %d" % status
    print "Function = %s" % func_name
    print "Message = %s" % err_msg
    print "Location = %s(%d)" % (file_name, line)
    print "User data = %r" % userdata

def silent_error_handler(status, func_name, err_msg, file_name, line, userdata):
    pass


print "** Default handler"
try:
    cv2.imshow("", None) # This causes an assert
except cv2.error as e:
    pass

print "** Using verbose handler"
cv2.redirectError(verbose_error_handler, 42)
try:
    cv2.imshow("", None) # This causes an assert
except cv2.error as e:
    pass

print "** Using silent handler"
cv2.redirectError(silent_error_handler)
try:
    cv2.imshow("", None) # This causes an assert
except cv2.error as e:
    pass

print "** Back to default handler"
cv2.redirectError(None)
try:
    cv2.imshow("", None) # This causes an assert
except cv2.error as e:
    pass

使用OpenCV的补丁版本(基于上述说明),我在控制台上得到以下输出:

** Default handler
OpenCV(3.4.1) Error: Assertion failed (size.width>0 && size.height>0) in cv::imshow, file F:\GitHub\opencv\modules\highgui\src\window.cpp, line 364
** Using verbose handler
Status = -215
Function = cv::imshow
Message = size.width>0 && size.height>0
Location = F:\GitHub\opencv\modules\highgui\src\window.cpp(364)
User data = 42
** Using silent handler
** Back to default handler
OpenCV(3.4.1) Error: Assertion failed (size.width>0 && size.height>0) in cv::imshow, file F:\GitHub\opencv\modules\highgui\src\window.cpp, line 364

就在我开始写这个答案时,我的一个想法是,由于default error handler使用以下格式化字符串将所有这些消息输出到stderr

"OpenCV(%s) Error: %s (%s) in %s, file %s, line %d"

我们也许可以钩住stderr流,过滤掉以常量前缀开头的任何行。唉,我没能做到这一点。也许其他人可以?在


Edit:Patched合并到opencv:master中,只做了一些小的修改(主要是我们去掉了user data参数,因为在Python中它是不必要的)。在

相关问题 更多 >