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

don't pip install opencv-python if opencv-contrib-python is installed #57

Closed
dcnieho opened this issue Dec 17, 2022 · 6 comments
Closed

Comments

@dcnieho
Copy link
Contributor

dcnieho commented Dec 17, 2022

I just pip-installed the current dev branch into the venv for my app. My app uses functionality from the opencv-contrib-python. After installing imgui_bundle, i now have both opencv-contrib-python and opencv-python installed, and trying to use functionality from the contrib version does not work.

In short, opencv-python should not be installed if opencv-contrib-python is already installed. I am not sure if there is a way to specify that with the dependency infrastructure (e.g. somehow to say that either of these is fine), but right now this messes with a perfectly fine set of pip packages ;)

@pthom
Copy link
Owner

pthom commented Dec 17, 2022

Humm.... DLL Hell approaching...

Strange however, I just retested this example under windows (not from this repo), which use an Oil painting effect from opencv-contrib .

image

So I would say it seems to kinda work on my computer.

Anyway, this is probably due to a DLL clash. I solved this under macOS and linux by compiling a minimalist version of OpenCV and statically linking it inside imgui_bundle. Please try it also and tell me if it helps:

demos/litgen/imgui_bundle/external/immvision/find_opencv.cmake:276

macro(immvision_find_opencv)
    if (IMGUI_BUNDLE_IMMVISION_FETCH_OPENCV)
        if (WIN32)
            set(IMGUIBUNDLE_OPENCV_WIN_USE_OFFICIAL_PREBUILT_460 ON)
        else()
            set(IMGUIBUNDLE_OPENCV_FETCH_SOURCE ON)
        endif()
    endif()

becomes:

macro(immvision_find_opencv)
    if (IMGUI_BUNDLE_IMMVISION_FETCH_OPENCV)
        set(IMGUIBUNDLE_OPENCV_FETCH_SOURCE ON)
    endif()

This will result in pip fetching OpenCV from source and compiling it, then statically link it into imgui_bundle.

@pthom
Copy link
Owner

pthom commented Dec 17, 2022

... Fetching + compiling a minimalist OpenCV will add 3'30" to the pip build time

@pthom
Copy link
Owner

pthom commented Dec 17, 2022

Ok, two things:

  1. my previous suggestion about changing imgui bundle build mode will not help since the issue lies between two opencv packages, not within imgui bundle.

So I guess the only solution is to remove opencv from the requirements (as far as i understood from reading the opencv contrib pipy page)

  1. Building opencv via pip currently fails on windows because of a known bug in cmake 3.25.20 : pyproject.toml shall exclude cmake 3.25.20. I will push this later
    3

@dcnieho
Copy link
Contributor Author

dcnieho commented Dec 17, 2022

This is a bit akin dll hell indeed. SUPER nice example by the way, would be nice to include somewhere, maybe as a third demo?

But yeah, fun new issue eh? So what happened exactly:

  1. opencv-contrib-python was already installed in my venv and working fine upon cv2 import
  2. installing imgui_bundle caused opencv-python to be installed
  3. import cv2 now loads opencv from opencv-python not opencv-contrib-python
  4. i uninstalled opencv-python
  5. now import cv2 cannot find the module, despite opencv-contrib-python still being present
  6. so i reinstalled opencv-contrib-python
  7. all is working fine now

Solutions:

  1. Yeah, one possible solution for now would be to not list opencv-python as a dependency, but then you have the problem that immvision demo won't run if there is no opencv package installed at all.
  2. The open-cv python readme explicitly says not to install only one of the packages, if you have more than one uninstall them all and reinstall the one you want. Perhaps we can add some code somewhere in the module loading to check for this situation and telling the user to rectify it? I don't like this.
  3. It would be great if opencv-python is installed by default, but advanced users can specify to not install it with something like imgui_bundle[no-opencv]. In a pyproject.toml file dependencies for extras are marked with, e.g., extra=="opencv", so it is maybe possible to add a specifier extra!='no-opencv' to an opencv-python (untested, not found on google...). But i think your dependencies instead come from setup.py, right? Then that would definitely not work. Seems rather hacky too
  4. The best solution would be if opencv-python would not install when opencv-contrib-python is already present. From a google this does not appear to be possible with pip. Will post this upstream.

@dcnieho
Copy link
Contributor Author

dcnieho commented Dec 17, 2022

Ah, we're not the first to run into this:
opencv/opencv-python#677

I think the solution they provide ("after install remove unused package variants") is not a good one because there will be plenty of packages listing imgui_bundle as a dependcy (mine's one) and at least some of those will also list opencv-contrib-python (again, mine). After just pip-installing such a package, the user will then have multiple opencv packages and need to do an uninstall. It also rather messes with my automated executable building as a github action.

Your solution is better. Its apparently what is commonly done as well for packages depending on tensorflow

Also relevant: https://discuss.python.org/t/conditional-package-install-depending-on-other-packages-in-environment/4140

@dcnieho
Copy link
Contributor Author

dcnieho commented Dec 17, 2022

I'll provide a PR

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

2 participants