Running multiple versions of OpenCV on the same computer

11,933

Solution 1

I have a working CMakelists.txt for almost the same configuration as you describe except that I am running a dauntingly old Ubuntu 12.04 (its not my own computer).

I believe your problem comes from this line:

find_package(OpenCV REQUIRED)

Which gives you access to your distribution's OpenCV 2.4. Then you are linking against the manually installed 3.2.x version. So problems arise as soon as the interface of a function you use has changed between the two version. Your first piece of code run by chance I think.

Here is my 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})

If you do not want to commit to your repository the hardcoded path to your install of OpenCV 3.2 you can refine this CMakeList.txt by changing the find_package line to:

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})

Then you just have to define the variable OPENCV_INSTALL_DIR before running cmake. I do that by exporting it from my .bashrc

Solution 2

Indeed, you're linking against system-default version of OpenCV.

Reconfigure your project by calling CMake with right path to file OpenCVConfig.cmake.

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

Find file CMakeCache.txt in your build directory. It contains internal CMake variables, OpenCV paths are also there.

Also, it is incorrect to hardcode paths. Use include_directories(${OPENCV_INCLUDE_DIRS})

And quotation from OpenCVConfig.cmake

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

Solution 3

While you are setting up the include files to use the newly installed OpenCV headers, you are linking against the opencv on your system path. The version is just stored in the headers, which is why it's outputting the expected version but failing to link. Try setting the variable "OpenCV_DIR" to the location of the OpenCVConfig.cmake file you want to use before running the find module.

See the documentation for your version of cmake here. Note the two modes that find_package can be run in (Module or Config mode).

Unless you are linking to static libraries, you will still have problems running your library / application. To fix that, you'll need to add the libraries to your LD_LIBRARY_PATH.

Share:
11,933

Related videos on Youtube

Tony Tarng
Author by

Tony Tarng

Updated on September 27, 2022

Comments

  • Tony Tarng
    Tony Tarng about 1 year

    My computer is running Ubuntu-16.04-LTS and OpenCV-2.4.13 is already installed on it. However, I would like to use the functionalities of newer versions of OpenCV, such as OpenCV-3.2.0 without removing the older version.

    So far I have downloaded OpenCV-3.2.0 and compiled and installed it. I am uing CMake to compile OpenCV, so I changed my CMakeLists.txt file to:

    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})
    

    Now, when I run this little piece of code,

    #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;
    }
    

    I get

    OpenCV version: 3.2.0

    instead of

    OpenCV version 2.4.13

    So everything seems to be in order, except when I start running some actual OpenCV functions such as:

    #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);
    }
    

    I get all these undefined reference errors:

    CMakeFiles/cv_io.dir/io.cpp.o: In function 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 const*)': io.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x40): undefined reference to cv::String::allocate(unsigned long)' CMakeFiles/cv_io.dir/io.cpp.o: In functioncv::String::~String()': io.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x10): undefined reference to cv::String::deallocate()' CMakeFiles/cv_io.dir/io.cpp.o: In functioncv::String::operator=(cv::String const&)': io.cpp:(.text.ZN2cv6StringaSERKS0[ZN2cv6StringaSERKS0]+0x2c): undefined reference to `cv::String::deallocate()' collect2: error: ld returned 1 exit status CMakeFiles/cv_io.dir/build.make:121: recipe for target 'cv_io' failed make2: * [cv_io] Error 1 CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/cv_io.dir/all' failed make1: * [CMakeFiles/cv_io.dir/all] Error 2 Makefile:83: recipe for target 'all' failed make: *** [all] Error 2

    Does anyone know how to solve this problem? I think the problem is that I'm still not linking all the libraries properly in the CMakeLists.txt. Also, I found a comment below this article mentioning something similar to what I'm experiencing, but I do not understand the page containing the solution it is referring to. I'm very new to OpenCV and CMake, so hopefully you can provide me instructions that are as explicit as possible. I've been stuck on this for forever, so any help is highly appreciated! Thank you very much!

    • yotabyte
      yotabyte about 6 years
      The pain of configuring two OpenCV versions. I feel you.
    • Gabriel Devillers
      Gabriel Devillers about 6 years
      @Srinivas While that should work that seems a bit overkill and heavy.
  • jhauris
    jhauris about 6 years
    He's not having run-time errors, this is during linking. The CMake command he's using is telling it to link against the wrong version of the libraries.
  • Tony Tarng
    Tony Tarng about 6 years
    @wl2776 I just ran cmake .. -DOpenCV_DIR=/home/ubuntu/opencv-3.2.0 then make but the undefined reference errors are still there. Also, originally i used include_directories(${OPENCV_INCLUDE_DIRS}), but when I ran the print version code, it would print OpenCV version: 2.4.13, so that's why i switched to what I'm using right now.