【问题标题】:Why does a right click open a drop down menu in my OpenCV imshow() window?为什么右键单击会在我的 OpenCV imshow() 窗口中打开一个下拉菜单?
【发布时间】:2019-06-17 00:07:49
【问题描述】:

我正在尝试在我的系统上运行OpenCV Grabcut Sample

  • OpenCV 4.1.0 版
  • Python 版本 3.6.8
  • IDLE 版本 3.6.8
  • Ubuntu 18.04.2

这是来自cv2.getBuildInformation() 的构建信息:

在 Grabcut 示例脚本中,我需要“使用 右键 鼠标按钮在对象周围绘制一个矩形。”由于某种原因,当我单击鼠标右键时会出现一个下拉菜单(这是我单击并按住鼠标右键):

这在以前没有发生过,但是自从我重新格式化了我的计算机并重新安装了 OpenCV 后,我得到了这个下拉菜单。 imshow 窗口看起来也不同。我尝试安装很多视频编解码器包 (from this tutorial),但没有帮助。

此下拉菜单会干扰鼠标回调函数。我怎样才能摆脱这个下拉菜单?

我使用命令pip3 install opencv-contrib-python 安装了OpenCV。我知道我丢失了一些包,所以我尝试安装(但失败了 - '找不到任何通过正则表达式的包...')这些包来自this tutorial

sudo apt-get install python-devel numpy
sudo apt-get install gcc gcc-c++
sudo apt-get install gtk2-devel
sudo apt-get install ffmpeg-devel
sudo apt-get install gstreamer-plugins-base-devel

【问题讨论】:

  • 我想对于这类问题,您应该添加有关您的操作系统(Ubuntu 18.04?)、Python 安装、IDE 等的详细信息(而且,总是您喜欢的动画!:-))
  • 这看起来像是highgui使用的后端的神器。那篇文章展示了如何使用 GTK。也许您以前使用过类似 Qt 的东西?无论如何,正如 HansHirse 所说,我们没有足够的信息可以确定。
  • @rob3c 我添加了有关我的系统的更多信息。我不确定我需要添加哪些信息。

标签: python opencv imshow


【解决方案1】:

在 Python 中,您可以将 cv2.WINDOW_GUI_NORMAL 标志传递给 namedWindow() 以禁用下拉菜单(仅当您有 Qt 后端时才支持该标志):

cv2.namedWindow("window_name", cv2.WINDOW_GUI_NORMAL)

然后调用

cv2.imshow("window_name", img)

namedWindow 函数文档的链接是here

【讨论】:

    【解决方案2】:

    您正在使用 Qt highgui 后端,它看起来像是强制右键单击上下文菜单而无法在不重新编译 opencv 的情况下禁用它。如果您之前没有看到它,很可能您使用的是不同的后端。

    如果您更喜欢使用 Qt 并且不介意稍微更改 opencv 源代码并重新构建,那么看起来就像更改文件 modules/highgui/src/window_QT.cpp 中的 DefaultViewPort::contextMenuEvent() 方法以跳过构建菜单并仅返回可能会起作用(或者有由于您添加了一些标志,它可以选择构建菜单)。目前,Qt highgui 后端使用常规菜单中可用的任何操作自动创建菜单。

    这是截至2019-06-18当前opencv master分支中方法的链接:

    https://github.com/opencv/opencv/blob/1d2ef6b2a14fd5f80277d64b14e4a9a2faddc7d8/modules/highgui/src/window_QT.cpp#L2697

    有这个代码:

    void DefaultViewPort::contextMenuEvent(QContextMenuEvent* evnt)
    {
        if (centralWidget->vect_QActions.size() > 0)
        {
            QMenu menu(this);
    
            foreach (QAction *a, centralWidget->vect_QActions)
                menu.addAction(a);
    
            menu.exec(evnt->globalPos());
        }
    }
    

    在不重新编译的情况下可能工作的替代方法可能是使用左拖动进行选择,同时检查是否按住了额外的修饰键(如 shift 或 ctrl)。

    顺便说一句,我还没有实际测试过这两种方法,祝你好运! :-)

    更新: 如果您仍然想要 Qt 但不需要花哨的菜单选项和额外的行为等,看起来您可以在创建窗口时添加 CV_GUI_NORMAL 标志以禁用 CV_GUI_EXPANDED Qt 功能。

    【讨论】:

    • 感谢您的帮助。使用修饰键是最简单的解决方案。我现在能够实现将 GrabCut 应用于 DL 模型的语义分割的目标:imgur.com/a/LdhJHZQ
    • 看起来效果不错!使用修饰键肯定比完全重新编译要好:-)
    • @StephenMeschke 你是如何实现 mod 键的?添加一些代码会很有用(请注意,不幸的是,我必须使用右键单击:我要杀死上下文菜单的方法是让用户双击,这会取消上下文菜单。这是一个 hack,但现在可以使用)。
    猜你喜欢
    • 2014-03-16
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多