【问题标题】:Running multiple versions of OpenCV on the same computer在同一台计算机上运行多个版本的 OpenCV
【发布时间】:2018-01-18 17:36:21
【问题描述】:

我的电脑正在运行 Ubuntu-16.04-LTS,并且已经安装了 OpenCV-2.4.13。但是,我想在不删除旧版本的情况下使用 OpenCV 较新版本的功能,例如 OpenCV-3.2.0。

到目前为止,我已经下载了 OpenCV-3.2.0 并编译并安装了它。我正在使用 CMake 编译 OpenCV,所以我将我的 CMakeLists.txt 文件更改为:

cmake_minimum_required (VERSION 3.2)

project(io)

find_package(OpenCV REQUIRED)

include_directories("/home/ubuntu/opencv-3.2.0/include") # directory of OpenCV-3.2.0
link_directories("/home/ubuntu/opencv-3.2.0/lib") # directory of OpenCV-3.2.0

add_executable(cv_io io.cpp)

target_link_libraries(cv_io ${OpenCV_LIBS})

现在,当我运行这段小代码时,

#include <iostream>
#include "opencv2/core/version.hpp"

int main(int argc, char ** argv)
{
  std::cout << "OpenCV version: "
            << CV_MAJOR_VERSION << "." 
            << CV_MINOR_VERSION << "."
            << CV_SUBMINOR_VERSION
            << std::endl;
  return 0;
}

我明白了

OpenCV 版本:3.2.0

而不是

OpenCV 2.4.13 版

所以一切似乎都井然有序,除非我开始运行一些实际的 OpenCV 函数,例如:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img = cv::imread("ferrari.jpg");

    cv::Mat dst;
    cv::Sobel(img, dst, CV_32F, 1, 1);

    cv::imwrite("ferrari_sobel.png", dst);

    cv::VideoCapture input(0);
}

我得到了所有这些未定义的引用错误:

CMakeFiles/cv_io.dir/io.cpp.o:在函数main': io.cpp:(.text+0x40): undefined reference tocv::imread(cv::String const&, int)' io.cpp:(.text+0xd4): undefined reference to cv::imwrite(cv::String const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)' CMakeFiles/cv_io.dir/io.cpp.o: In functioncv::String::String(char 常量*)': io.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x40): 对cv::String::allocate(unsigned long)' CMakeFiles/cv_io.dir/io.cpp.o: In functioncv::String::~String()' 的未定义引用: io.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x10): 未定义 参考cv::String::deallocate()' CMakeFiles/cv_io.dir/io.cpp.o: In functioncv::String::operator=(cv::String const&)': io.cpp:(.text.ZN2cv6StringaSERKS0[ZN2cv6StringaSERKS0]+0x2c): 未定义对 `cv::String::deallocate()' collect2 的引用:错误:ld 返回 1 个退出状态 CMakeFiles/cv_io.dir/build.make:121: recipe for 目标 'cv_io' 失败 make2: * [cv_io] 错误 1 CMakeFiles/Makefile2:67:目标“CMakeFiles/cv_io.dir/all”的配方 失败 make1: * [CMakeFiles/cv_io.dir/all] 错误 2 Makefile:83: 目标“所有”的配方失败 make: *** [all] 错误 2

有谁知道如何解决这个问题?我认为问题在于我仍然没有在CMakeLists.txt 中正确链接所有库。另外,我发现a comment below this article 提到了与我正在经历的事情类似的事情,但我不明白the page containing the solution 它指的是什么。 我对 OpenCV 和 CMake 非常陌生,因此希望您能向我提供尽可能明确的说明。我一直坚持这一点,所以非常感谢任何帮助!非常感谢!

【问题讨论】:

  • 配置两个 OpenCV 版本的痛苦。我感觉到你了。
  • 如果您有兴趣,可以在 Docker 容器上运行两个版本。在不影响系统范围的包的情况下配置多个版本会容易得多
  • @Srinivas 虽然这似乎有点矫枉过正和沉重。

标签: c++ opencv ubuntu cmake


【解决方案1】:

我有一个可用的CMakelists.txt,其配置与您描述的几乎相同,只是我运行的是一台非常旧的 Ubuntu 12.04(它不是我自己的计算机)。

我相信你的问题来自这一行:

find_package(OpenCV REQUIRED)

这使您可以访问您的发行版的 OpenCV 2.4。然后您将链接到手动安装的 3.2.x 版本。因此,一旦您使用的函数的接口在两个版本之间发生变化,就会出现问题。我认为你的第一段代码是偶然运行的。

这是我的CMakeList.txt

cmake_minimum_required(VERSION 2.8)
project(demo)

find_package(OpenCV 3.2 REQUIRED PATHS "/path/to/OCV3.2/install/dir/")

include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(main main.cpp)
target_link_libraries(main ${OpenCV_LIBS})

如果您不想将安装 OpenCV 3.2 的硬编码路径提交到您的存储库,您可以通过将 find_package 行更改为:

来优化此 CMakeList.txt
if(DEFINED ENV{OPENCV_INSTALL_DIR})
    find_package(OpenCV 3.2 REQUIRED PATHS $ENV{OPENCV_INSTALL_DIR})
else()
    message("OPENCV_INSTALL_DIR not set, searching in default location(s)")
    find_package(OpenCV 3.2 REQUIRED)
endif(DEFINED ENV{OPENCV_INSTALL_DIR})

那么你只需要在运行cmake之前定义变量OPENCV_INSTALL_DIR。我通过从我的.bashrc 导出它来做到这一点

【讨论】:

    【解决方案2】:

    当您设置包含文件以使用新安装的 OpenCV 头文件时,您正在链接系统路径上的 opencv。该版本仅存储在标头中,这就是它输出预期版本但无法链接的原因。尝试在运行 find 模块之前将变量“OpenCV_DIR”设置为您要使用的 OpenCVConfig.cmake 文件的位置。

    请参阅您的 cmake here 版本的文档。注意 find_package 可以运行的两种模式(Module 或 Config 模式)。

    除非您链接到静态库,否则您在运行库/应用程序时仍然会遇到问题。要解决此问题,您需要将库添加到 LD_LIBRARY_PATH。

    【讨论】:

      【解决方案3】:

      确实,您链接的是 OpenCV 的系统默认版本。

      通过使用正确的文件 OpenCVConfig.cmake 的路径调用 CMake 来重新配置您的项目。

      cmake /path/to/your/sources -DOpenCV_DIR=/home/ubuntu/opencv-3.2.0

      在您的构建目录中找到文件CMakeCache.txt。它包含内部 CMake 变量,OpenCV 路径也在那里。

      另外,硬编码路径是不正确的。使用include_directories(${OPENCV_INCLUDE_DIRS})

      以及来自OpenCVConfig.cmake的引用

        - OpenCV_LIB_DIR                  : The directory(es) where lib files are. Calling LINK_DIRECTORIES
                                           with this path is NOT needed.
      

      【讨论】:

      • 他没有运行时错误,这是在链接期间。他使用的 CMake 命令告诉它链接到错误版本的库。
      • @wl2776 我刚跑了cmake .. -DOpenCV_DIR=/home/ubuntu/opencv-3.2.0 然后make 但未定义的参考错误仍然存​​在。另外,最初我使用include_directories(${OPENCV_INCLUDE_DIRS}),但是当我运行打印版本代码时,它会打印OpenCV version: 2.4.13,所以这就是为什么我切换到我现在使用的。
      猜你喜欢
      • 2014-08-08
      • 2010-12-19
      • 2022-10-14
      • 2018-06-02
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多