2017-08-10 25 views
12

Máy tính của tôi đang chạy Ubuntu-16.04-LTS và OpenCV-2.4.13 đã được cài đặt trên đó. Tuy nhiên, tôi muốn sử dụng các chức năng của các phiên bản OpenCV mới hơn, chẳng hạn như OpenCV-3.2.0 mà không xóa phiên bản cũ hơn.Chạy nhiều phiên bản OpenCV trên cùng một máy tính

Cho đến nay tôi đã tải xuống OpenCV-3.2.0 và biên dịch và cài đặt nó. Tôi uing CMake để biên dịch OpenCV, vì vậy tôi đã thay đổi tập tin CMakeLists.txt tôi để:

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

Bây giờ, khi tôi chạy đôi chút mã này,

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

tôi nhận được

OpenCV version: 3.2.0

thay vì

OpenCV version 2.4.13

Vì vậy, tất cả mọi thứ có vẻ là theo thứ tự, trừ khi tôi bắt đầu chạy một số chức năng OpenCV thực tế như:

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

tôi nhận được tất cả các lỗi này tham khảo không xác định:

CMakeFiles/cv_io.dir/io.cpp.o: In function main': io.cpp:(.text+0x40): undefined reference to cv::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 function cv::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 function cv::String::~String()': io.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x10): undefined reference to cv::String::deallocate()' CMakeFiles/cv_io.dir/io.cpp.o: In function cv::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 make 2 : * [cv_io] Error 1 CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/cv_io.dir/all' failed make 1 : * [CMakeFiles/cv_io.dir/all] Error 2 Makefile:83: recipe for target 'all' failed make: *** [all] Error 2

Có ai biết làm thế nào để giải quyết vấn đề này? Tôi nghĩ rằng vấn đề là tôi vẫn không liên kết tất cả các thư viện đúng trong CMakeLists.txt. Ngoài ra, tôi tìm thấy a comment below this article đề cập đến một cái gì đó tương tự như những gì tôi đang gặp, nhưng tôi không hiểu the page containing the solution nó đang đề cập đến. Tôi rất mới với OpenCV và CMake, vì vậy hy vọng bạn có thể cung cấp cho tôi hướng dẫn rõ ràng nhất có thể. Tôi đã bị mắc kẹt trên này cho mãi mãi, vì vậy bất kỳ trợ giúp được đánh giá cao! Cảm ơn nhiều!

+0

Sự đau đớn của việc định cấu hình hai phiên bản OpenCV của tôi. Tôi cảm thấy bạn. – Yotam

+0

Nếu bạn quan tâm, bạn có thể chạy hai phiên bản trên vùng chứa Docker. Nó sẽ dễ dàng hơn nhiều để cấu hình nhiều phiên bản mà không ảnh hưởng đến các gói toàn hệ thống – Srinivas

+1

@Srinivas Trong khi đó, công việc đó có vẻ hơi quá mức và nặng nề. –

Trả lời

3

Tôi có CMakelist.txt đang hoạt động cho hầu hết cấu hình giống như bạn mô tả ngoại trừ việc tôi đang chạy Ubuntu 12.04 cũ (không phải máy tính của riêng tôi).

Tôi tin rằng vấn đề của bạn xuất phát từ dòng này:

find_package(OpenCV REQUIRED) 

Mà cho bạn truy cập vào OpenCV phân phối của bạn 2.4. Sau đó, bạn đang liên kết với phiên bản 3.2.x được cài đặt theo cách thủ công. Vì vậy, các vấn đề phát sinh ngay khi giao diện của một hàm bạn sử dụng đã thay đổi giữa hai phiên bản. Đoạn mã đầu tiên của bạn chạy theo cơ hội tôi nghĩ.

Đây là tôi 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}) 

Nếu bạn không muốn cam kết kho của bạn con đường mã hóa cứng để bạn cài đặt của OpenCV 3.2 bạn có thể tinh chỉnh này CMakeList.txt bằng cách thay đổi dòng find_package tới:

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

Sau đó, bạn chỉ cần xác định biến OPENCV_INSTALL_DIR trước khi chạy cmake. Tôi làm điều đó bằng cách xuất nó từ .bashrc

+0

Nó hoạt động !! Cảm ơn bạn rất nhiều! –

1

Thật vậy, bạn đang liên kết với phiên bản OpenCV mặc định của hệ thống.

Định cấu hình lại dự án của bạn bằng cách gọi CMake với đường dẫn phải để mở tệp OpenCVConfig.cmake.

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

Tìm tập tin trong thư mục CMakeCache.txt xây dựng của bạn. Nó chứa các biến CMake bên trong, các đường dẫn OpenCV cũng ở đó.

Ngoài ra, việc mã hóa đường dẫn sẽ không chính xác. Sử dụng include_directories(${OPENCV_INCLUDE_DIRS})

Và trích dẫn từ OpenCVConfig.cmake

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

Anh ấy không gặp lỗi thời gian chạy, đây là lúc liên kết. Lệnh CMake mà anh ta đang sử dụng đang bảo nó liên kết với phiên bản sai của các thư viện. – jhauris

+0

@jhauris, vâng, bạn nói đúng, cảm ơn vì đã chỉ ra điều đó. – wl2776

+0

@ wl2776 Tôi chỉ chạy 'cmake .. -DOpenCV_DIR =/home/ubuntu/opencv-3.2.0' rồi' make' nhưng các lỗi tham chiếu chưa xác định vẫn còn đó. Ngoài ra, ban đầu tôi sử dụng 'include_directories ($ {OPENCV_INCLUDE_DIRS})', nhưng khi tôi chạy mã phiên bản in, nó sẽ in 'OpenCV phiên bản: 2.4.13', vì vậy đó là lý do tại sao tôi chuyển sang những gì tôi đang sử dụng ngay bây giờ. –

1

Trong khi bạn đang thiết lập các tập tin bao gồm sử dụng các tiêu đề OpenCV mới được cài đặt, bạn đang liên kết chống lại opencv trên đường dẫn hệ thống của bạn. Phiên bản này chỉ được lưu trữ trong các tiêu đề, đó là lý do tại sao nó xuất ra phiên bản dự kiến ​​nhưng không liên kết. Thử đặt biến "OpenCV_DIR" thành vị trí của tệp OpenCVConfig.cmake mà bạn muốn sử dụng trước khi chạy mô-đun tìm.

Xem tài liệu về phiên bản cmake here của bạn. Lưu ý hai chế độ find_package có thể chạy trong (chế độ Mô-đun hoặc Config).

Trừ khi bạn đang liên kết với các thư viện tĩnh, bạn sẽ vẫn gặp sự cố khi chạy thư viện/ứng dụng của mình. Để khắc phục điều đó, bạn cần thêm thư viện vào LD_LIBRARY_PATH của mình.

Các vấn đề liên quan