Мой компьютер работает 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);
}
Я получаю все эти справочные ошибки undefined:
CMakeFiles/cv_io.dir/io.cpp.o: В функции
main': io.cpp:(.text+0x40): undefined reference to
cv:: imread (cv:: String const &, int) 'io.cpp: (. text + 0xd4): undefined ссылка наcv::imwrite(cv::String const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)' CMakeFiles/cv_io.dir/io.cpp.o: In function
резюме:: Строка:: String (charсопз *) ':. Io.cpp:( text._ZN2cv6StringC2EPKc [_ZN2cv6StringC5EPKc] + 0x40): undefined ссылка наcv::String::allocate(unsigned long)' CMakeFiles/cv_io.dir/io.cpp.o: In function
cv:: String:: ~ String() ': io.cpp:(. text._ZN2cv6StringD2Ev [_ZN2cv6StringD5Ev] + 0x10): undefinedссылка на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 ссылка на `cv:: String:: deallocate() 'collect2: error: ld вернулся 1 статус выхода CMakeFiles/cv_io.dir/build.make: 121: рецепт для target 'cv_io' не удалось сделать 2: * [cv_io] Ошибка 1 CMakeFiles/Makefile2: 67: рецепт для цели "CMakeFiles/cv_io.dir/all" не удалось сделать 1: * [CMakeFiles/cv_io.dir/all] Ошибка 2 Makefile: 83: рецепт для цели "все" не удалось: *** [все] Ошибка 2
Кто-нибудь знает, как решить эту проблему? Я думаю, проблема в том, что я все еще не связываю все библиотеки правильно в CMakeLists.txt
. Кроме того, я нашел комментарий ниже этой статьи, в котором упоминается нечто похожее на то, что я испытываю, но я не понимаю страница, содержащая решение, о котором идет речь. Я очень новичок в OpenCV и CMake, поэтому, надеюсь, вы можете предоставить мне инструкции, которые настолько ясны, насколько это возможно. Я застрял на этом навсегда, поэтому любая помощь высоко ценится! Большое спасибо!
У меня есть рабочий CMakelist.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, вы можете уточнить этот CMakelist.txt
, изменив строку find_package
на:
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})
Тогда вам просто нужно определить переменную OPENCV_INSTALL_DIR
перед запуском cmake. Я делаю это, экспортируя его из моего .bashrc
Пока вы настраиваете включенные файлы для использования вновь установленных заголовков OpenCV, вы связываетесь с opencv на вашем системном пути. Версия просто хранится в заголовках, поэтому она выводит ожидаемую версию, но не связывает ее. Попробуйте установить переменную "OpenCV_DIR" в местоположение файла OpenCVConfig.cmake, который вы хотите использовать до запуска модуля поиска.
Смотрите документацию для вашей версии cmake здесь. Обратите внимание на два режима, в которых может быть найден find_package (режим Module или Config).
Если вы не связываетесь со статическими библиотеками, у вас все еще будут проблемы с запуском вашей библиотеки/приложения. Чтобы исправить это, вам нужно добавить библиотеки в LD_LIBRARY_PATH.
Действительно, вы связываетесь с версией OpenCV по умолчанию, установленной по умолчанию.
Переконфигурируйте свой проект, вызвав CMake с правильным путем в файл OpenCVConfig.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.