Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing cv2 prevents matplotlib from working #386

Closed
TahaDz opened this issue Sep 5, 2020 · 5 comments
Closed

Importing cv2 prevents matplotlib from working #386

TahaDz opened this issue Sep 5, 2020 · 5 comments

Comments

@TahaDz
Copy link

TahaDz commented Sep 5, 2020

System information (version)

  • OpenCV => 4.4.0.
  • Operating System / Platform => ubuntu 20.04 lts
  • Python => 3.8
  • PyQt : 5.15.0
  • Matplotlib version: 3.3.1

Detailed description

Hello,
i used to work with matplotlib and opencv normally until i installed PyQt, whenever i import cv2 in the same file as matplotlib, matplotlib fuctions don't work (i tried in terminal and pycharm)
here is an example of the code :

import matplotlib
import matplotlib.pyplot as plt
import cv2
plt.plot(range(5))
plt.show()

that's what i get :

QObject::moveToThread: Current thread (0x199fcb0) is not the object's thread (0x1ae4c70).
Cannot move to target thread (0x199fcb0)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/taha/.local/lib/python3.8/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl.

Aborted (core dumped)

i reported this ISSUE problem to matplotlib packagers but they said they cant do anything from their side.

another thing is that i am using cv2 for a small animation, whenever i execute the code it works normally but it prints this message :

Qt: Session management error: None of the authentication protocols specified are supported

Thank you.

@skvark
Copy link
Member

skvark commented Sep 5, 2020

Don't use PyQt and opencv-python together. Instead, use opencv-python-headless which does not have dependency to Qt.

Multiple Qt versions shipped by different packages will not work properly. Just use one GUI library at a time. In this case you have two different Qt versions in use, another from opencv-python and another one from PyQt. You must select one of them. Given that the OpenCV Qt bindings are very limited and useful mostly for debugging purposes, you should probably use just opencv-python-headless and create your GUI with PyQt.

This is also explained in the Installation and usage part of the README of this project:

b. Packages for server (headless) environments (such as Docker, cloud environments etc.)

These packages are smaller than the two other packages above because they do not contain any GUI functionality (not compiled with Qt / other GUI components). This means that the packages avoid a heavy dependency chain to X11 libraries and you will have for example smaller Docker images as a result. You should always use these packages if you do not use cv2.imshow et al. or you are using some other package than OpenCV to create your GUI.

PyQt and opencv-python will not work properly together because opencv-python sets some environment variables to load Qt platform plugins correctly for the Qt version which has been embedded to the pre-built wheels. This breaks PyQt, because the plugins in opencv-python package are not compatible with the PyQt Qt. I don't know how that can have a side effect to matplotlib, probably because it uses PyQt somehow and can't load it because PyQt reads the wrong environment variables.

TL;DR

Do not use multiple packages which ship with their own copy of Qt together. opencv-python-headless and opencv-contrib-python-headless do not have dependencies to Qt and can be safely used with PyQt.

@skvark skvark closed this as completed Sep 5, 2020
@tacaswell
Copy link

A possibly naive question, could the opencv-python depend on pyqt5 instead of bundling its own Qt?

@skvark
Copy link
Member

skvark commented Sep 6, 2020

In theory maybe, but very hard or impossible to implement reliably. Qt and other OpenCV third party dependencies come from the C++ code and are determined during build time. This package would have to be built against a specific version of PyQt5 (which in turn would have to be modified to ship with Qt development headers to begin with) and linker should be somehow tricked to load Qt from the PyQt5 package during runtime. It would be a huge mess to implement and maintain since Python's packaging ecosystem does not understand anything about binary dependencies.

Imho OpenCV should be able load Qt / GTK etc. during runtime (not possible currently) instead of having hard link time dependencies to those libraries. Then I could ship just the core and OpenCV could load compatible GUI backend if it's found on user's machine. However, this would require quite large rewrite to the OpenCV C++ code since this repository provides only a toolchain for packaging and publishing the OpenCV Python bindings binary and does not contain any actual OpenCV code.

@tacaswell
Copy link

Would it be possible to wrap the functions in cv2 that might hit Qt to set the envs at the last possible moment? Something like

import functools
_tripped = False

def _wrapper_factory(func):
    @functools.wraps(func)
    def _wrapper(*args, **kwargs):
         global _tripped
         if not _tripped:
             # do env setting logic
             _tripped = True
         return func(*args, **kwargs)

locals().update({k: _wrapper_factory(locals()[k]) for k in LIST_OF_QT_FUNCTION})

It isn't a great option, but it may keep some users from accidentally stepping into this trap...

@skvark
Copy link
Member

skvark commented Sep 7, 2020

Thanks for the suggestion, I'll think about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants