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

[Bug]: SIGSEGV segfault when setting a backend together with opencv #24364

Closed
epbuennig opened this issue Nov 4, 2022 · 3 comments
Closed

[Bug]: SIGSEGV segfault when setting a backend together with opencv #24364

epbuennig opened this issue Nov 4, 2022 · 3 comments
Labels

Comments

@epbuennig
Copy link

Bug summary

When importing matplotlib.pyplot and then setting a backend for matplotlib before using opencv the first call to imshow causes a segmentation fault.

I've opened an issue here, which was marked as 3rdparty as it apparently occurred in matplotlib.pyplot.

See additional info.

Code for reproduction

import matplotlib as mpl
import cv2

# swapping the order of thsese also resolves the issue
from matplotlib import pyplot as plt # removing this import resoves the issue
mpl.use('GTK3Agg') # remvoing this also resovle the issue

def test():
    webcam = cv2.VideoCapture(0)

    try:
        while True:
            ret, frame = webcam.read()

            # segfault happens on the first call to `imshow`
            cv2.imshow('frame', frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    finally:
        webcam.release()
        cv2.destroyAllWindows()


test()

Actual outcome

A segfault with no additional info

Expected outcome

A simple window opening displaying the video stream, no output from mpl

Additional information

This was a long time ago and since it segfaulted I don't have the state of the repo at the time as a commit. I simply entered some info in this template from what I could gather out of the other issue.

I think opencv uses a qt backend for cv2.highgui by default.

Please check out the linked issue, it contains some more information.
I'm just reporting it because I found nothing about it here yet, I don't have to investigate this further myself currently, I hope somebody else can reproduce it.

Operating system

Arch Linux 5.19.7-arch1-1 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

Matplotlib Version

3.5.3

Matplotlib Backend

gtk3agg

Python version

3.9.13

Jupyter version

No response

Installation

pip

@epbuennig
Copy link
Author

I may find some time to try to reproduce it over the holidays by the end of this year. If so, I could update the issue description to be more specific.

@tacaswell
Copy link
Member

Does this reproduce with mpl 3.6.2 (I suspect it does)?

Given that mpl is imported first and the segfault is in openCV, the solution almost certainly has to be in opencv.

What I think is going on here is:

  • at the top level we track in rcparams what backend the user want as a string (well technically as a sentinel or a string, but leave that aside)
  • if you never actually make a figure we do not do any of the GUI imports / set up (so you can change you mind later)
  • but if you use mpl.switch_backend and matplotlib.pyplot is imported we force the switch and that will do the imports

so:

  • if you do not import pyplot at all we never try to set up the GUI stuff so everything is fine
  • if you call switch_backend first all you are doing is setting a string, no GUI stuff is imported so you are fine
  • if you import pyplot and then switch the backend we will import gtk related things

My very strong suspicion is that you can reproduce this with just the gtk imports (copy them out of our backends to test). My guess is that the GUI frameworks are conflicting (we do a bunch of work to detect if one is already imported and to use it) or a packaging problem with a different version of an underlying linked library was found based on what order other libraries are loaded.

I'm going to close this (sorry to play hot-potato) because I do not think there is anything we can do on the Matplotlib side to fix this. To aid opencv in debuggin this I suggest checking sys.modules to see exactly what GUI libraries are imported when.

@tacaswell tacaswell closed this as not planned Won't fix, can't repro, duplicate, stale Nov 4, 2022
@ksunden
Copy link
Member

ksunden commented Nov 4, 2022

this seems to be a poor interaction between opencv and gobject, not anything to do with matplotlib specifically (other than that gi gets imported by the Gtk3Agg backend)

#import matplotlib as mpl
import cv2

# swapping the order of thsese also resolves the issue
#from matplotlib import pyplot as plt # removing this import resoves the issue
#mpl.use('Gtk3Agg') # remvoing this also resovle the issue

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gio, GLib, GObject, Gtk, Gdk

def test():
    webcam = cv2.VideoCapture(0)

    try:
        while True:
            ret, frame = webcam.read()

            # segfault happens on the first call to `imshow`
            cv2.imshow('frame', frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    finally:
        webcam.release()
        cv2.destroyAllWindows()


test()

Does reproduce, as @tacaswell suggested.

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

No branches or pull requests

3 participants