[solved] Build OpenCV with gtk and python

Hi,

I’m trying to get OpenCV in python to show a GUI. I have a default.nix that I invoke with nix-shell:

with import <nixpkgs> {};
(let

foo="bar";

in

stdenv.mkDerivation {
  name = "impurePythonEnv";
  buildInputs = [
    (python37.buildEnv.override {
      extraLibs = [
	pkgs.python37Packages.matplotlib
	pkgs.python37Packages.numpy
	pkgs.python37Packages.scipy
	pkgs.python37Packages.gnureadline        
        pkgs.python37Packages.opencv4
      ];
      ignoreCollisions = true;
    })
  ];
  shellHook = ''
        # set SOURCE_DATE_EPOCH so that we can use python wheels
        SOURCE_DATE_EPOCH=$(date +%s)
        export LANG=en_US.UTF-8	
  '';
})

Unfortunately this doesn’t work:

Traceback (most recent call last):
  File "test_webcam.py", line 18, in <module>
    cv.imshow('frame', gray)
cv2.error: OpenCV(4.1.2) /build/source/modules/highgui/src/window.cpp:651: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

I’m trying to marshall the information in this:

into my default.nix above, but I don’t really have enough of a feel for nix-the-language for this to work. Could anyone help me please?

Thanks,

Nawal.

1 Like

Example attempt (no re-building happens, same error as before):

with import <nixpkgs> {};
(

let python =
    let
    packageOverrides = self:
    super: {
      opencv4 = super.opencv4.override {
        enableGtk2 = true;
        gtk2 = pkgs.gtk2;
        enableFfmpeg = true; #here is how to add ffmpeg and other compilation flags
        ffmpeg_3 = pkgs.ffmpeg-full;
        };
    };
    in
      pkgs.python37.override {inherit packageOverrides; self = python;};

in

stdenv.mkDerivation {
  name = "impurePythonEnv";
  buildInputs = [
    (python37.buildEnv.override {
      extraLibs = [
	pkgs.python37Packages.matplotlib
	pkgs.python37Packages.numpy
	pkgs.python37Packages.scipy
	pkgs.python37Packages.gnureadline        
        pkgs.python37Packages.opencv4
      ];
      ignoreCollisions = true;
    })
  ];
  shellHook = ''
        # set SOURCE_DATE_EPOCH so that we can use python wheels
        SOURCE_DATE_EPOCH=$(date +%s)
        export LANG=en_US.UTF-8	
  '';
})

You are defining new python variable but you still use non-overridden python37 and pkgs.python37Packages in the derivation. Try replacing them with python and python.pkgs, respectively.

1 Like

Thank you, will try that!

Thanks @jtojnar , it worked!

with import <nixpkgs> {};
(

let python =
    let
    packageOverrides = self:
    super: {
      opencv4 = super.opencv4.override {
        enableGtk2 = true;
        gtk2 = pkgs.gtk2;
        enableFfmpeg = true; #here is how to add ffmpeg and other compilation flags
        };
    };
    in
      pkgs.python37.override {inherit packageOverrides; self = python;};

in

stdenv.mkDerivation {
  name = "impurePythonEnv";
  buildInputs = [
    imagemagick
    v4l-utils
    (python37.buildEnv.override {
      extraLibs = [
	pkgs.python37Packages.matplotlib
	pkgs.python37Packages.numpy
	pkgs.python37Packages.scipy
	pkgs.python37Packages.gnureadline        
        python.pkgs.opencv4
      ];
      ignoreCollisions = true;
    })
  ];
  shellHook = ''
        # set SOURCE_DATE_EPOCH so that we can use python wheels
        SOURCE_DATE_EPOCH=$(date +%s)
        export LANG=en_US.UTF-8	
  '';
})

2 Likes