如何让OpenCV在nix中运行?

时间:2016-11-18 00:11:46

标签: c++ linux opencv nix

我正在尝试使用nix包管理器来使用OpenCV hello world程序,但它会出现错误:

  

OpenCV错误:未指定错误(该功能未实现。使用Windows,GTK + 2.x或Carbon支持重建库。如果您使用的是Ubuntu或Debian,请安装libgtk2.0-dev和pkg-config,然后重新安装cvNamedWindow中的-run cmake或configure脚本),文件/tmp/nix-build-opencv-2.4.13.drv-0/opencv-2.4.13-src/modules/highgui/src/window.cpp,第483行   在抛出'cv :: Exception'的实例后调用终止what():/ tmp / nix-build-opencv-2.4.13.drv-0/opencv-2.4.13-src/modules/highgui/src/window。 cpp:483:错误:( - 2)该功能未实现。使用Windows,GTK + 2.x或Carbon支持重建库。如果您使用的是Ubuntu或Debian,请安装libgtk2.0-dev和pkg-config,然后在cvNamedWindow函数中重新运行cmake或configure脚本

我使用以下default.nix文件创建了一个nix-shell

with import <nixpkgs> {}; {
  cimgEnv = stdenv.mkDerivation {
  name = "cimgdev";
  buildInputs = [ pkgconfig stdenv cimg xorg.libX11 boost opencv gnome.gtk ];
  }; 
}

编译并运行以下代码

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main() {

  Mat image;

  image = imread("lena.jpg", 1);

  if ( !image.data ) {
    cout << "No image data" << endl;
    return -1;
  }

  namedWindow("Display Image", WINDOW_AUTOSIZE);
  imshow("Display Image", image);

  waitKey(0);

  return 0;
}

使用以下命令

g++ `pkg-config --cflags opencv` opencvtest.cpp `pkg-config --libs opencv` -o opencvtest

它编译,但如果我尝试运行它,我会收到上一条错误消息。

我尝试了CMake,结果相同。

3 个答案:

答案 0 :(得分:0)

第一眼看this.

看起来你的OpenCV版本缺少UI support适当的平台(主要是在highgui库中)。我从OpenCV CMakeLists.txt

获得这些东西
status("")
status("  GUI: ")

if(HAVE_QT5)
  status("    QT 5.x:"            HAVE_QT        THEN "YES (ver ${Qt5Core_VERSION_STRING})" ELSE NO)
  status("    QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${Qt5OpenGL_LIBRARIES} ${Qt5OpenGL_VERSION_STRING})" ELSE NO)
elseif(HAVE_QT)
  status("    QT 4.x:"            HAVE_QT        THEN "YES (ver ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} ${QT_EDITION})" ELSE NO)
  status("    QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${QT_QTOPENGL_LIBRARY})" ELSE NO)
else()
  if(DEFINED WITH_QT)
    status("    QT:" NO)
  endif()
  if(DEFINED WITH_WIN32UI)
    status("    Win32 UI:" HAVE_WIN32UI THEN YES ELSE NO)
  else()
    if(APPLE)
      if(WITH_CARBON)
        status("    Carbon:" YES)
      else()
        status("    Cocoa:"  YES)
      endif()
    else()
      if(HAVE_GTK3)
        status("    GTK+ 3.x:" HAVE_GTK THEN "YES (ver ${ALIASOF_gtk+-3.0_VERSION})" ELSE NO)
      elseif(HAVE_GTK)
        status("    GTK+ 2.x:" HAVE_GTK THEN "YES (ver ${ALIASOF_gtk+-2.0_VERSION})" ELSE NO)
      else()
        status("    GTK+:" NO)
      endif()
      status("    GThread :" HAVE_GTHREAD THEN "YES (ver ${ALIASOF_gthread-2.0_VERSION})" ELSE NO)
      status("    GtkGlExt:" HAVE_GTKGLEXT THEN "YES (ver ${ALIASOF_gtkglext-1.0_VERSION})" ELSE NO)
    endif()
  endif()
endif()

status("    OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO)
status("    VTK support:" HAVE_VTK THEN "YES (ver ${VTK_VERSION})" ELSE NO)

您可以看到很多GUI支持,包括Gtk2。所以安装ibgtk2.0-dev和pkg-config如上所述。确保HAVE_GTK变量有效。在由CMake配置之后,默认情况下GTK的支持将为ON。否则你可以检查一下。

如果您看到任何不正确的内容,请编辑/评论。

答案 1 :(得分:0)

OpenCV是在没有GTK支持的情况下构建的。在opencv package definition中,df <- dplyr::full_join(df1, df2) library( zoo ) library( data.table ) dt <- setDT(df)[, `:=`( sex = zoo::na.locf( zoo::na.locf( sex, na.rm = FALSE ) ), age = zoo::na.locf( zoo::na.locf( age, na.rm = FALSE ) ) ), by = id ] dt # id sex age x wave # 1: 1 1 22 -1.03971504 wave1 # 2: 2 2 22 -0.40848104 wave1 # 3: 3 1 18 -0.32354030 wave1 # 4: 4 2 23 0.01220463 wave1 # 5: 5 1 24 0.83800380 wave1 # 6: 6 2 19 0.31674395 wave1 # 7: 7 1 22 -0.62997068 wave1 # 8: 8 2 19 -0.02830660 wave1 # 9: 9 1 23 -0.48257814 wave1 # 10: 10 2 24 -0.82725441 wave1 # 11: 1 1 22 -2.04179796 wave2 # 12: 2 2 22 1.66578389 wave2 # 13: 3 1 18 0.63893257 wave2 # 14: 4 2 23 0.37758646 wave2 # 15: 5 1 24 -1.64174887 wave2 # 16: 6 2 19 -2.93152667 wave2 # 17: 7 1 22 0.14474519 wave2 # 18: 8 2 19 -1.18826640 wave2 # 19: 9 1 23 0.68365951 wave2 # 20: 10 2 24 -0.21636650 wave2 默认为enableGtk2。要启用它,请覆盖false中的参数: default.nix

除非您想直接使用 let opencvGtk = opencv.override (old : { enableGtk2 = true; }); in ... buildInputs = [... opencvGtk ...]; ... ,否则无需将gtk2之外的任何内容添加到pkgconfig中。 在冗长的opencv重建之后,构建并运行以上代码即可(根据buildInputs):

it works

答案 2 :(得分:0)

我知道这个问题是针对 C++ 的,但由于这个页面是 Google 上为寻找与 python 相同问题的人的第一个结果,我认为为 python 提供解决方案也很有用......

这里是一个 shell.nix 示例(用您选择的版本替换 python37):

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  name = "dev-shell";
  buildInputs = [
    pkgs.python37Packages.numpy
    pkgs.python37Packages.flask
    # …
    (pkgs.python37Packages.opencv4.override { enableGtk2 = true; })
  ];
}

或者以更简洁的方式:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  name = "dev-shell";
  buildInputs = with pkgs.python37Packages; [
    numpy
    flask
    # …
    (opencv4.override { enableGtk2 = true; })
  ];
}