Mon ordinateur exécute Ubuntu-16.04-LTS et OpenCV-2.4.13 est déjà installé dessus. Cependant, je voudrais utiliser les fonctionnalités des versions plus récentes d'OpenCV, comme OpenCV-3.2.0 sans supprimer l'ancienne version.
Jusqu'à présent, j'ai téléchargé OpenCV-3.2.0 et l'ai compilé et installé. J'utilise CMake pour compiler OpenCV, j'ai donc changé mon fichier CMakeLists.txt
En:
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})
Maintenant, quand je lance ce petit morceau de 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;
}
Je reçois
Version OpenCV: 3.2.0
au lieu de
OpenCV version 2.4.13
Donc, tout semble être en ordre, sauf lorsque je commence à exécuter certaines fonctions OpenCV réelles telles que:
#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);
}
J'obtiens toutes ces erreurs de référence non définies:
CMakeFiles/cv_io.dir/io.cpp.o: Dans la fonction
main': io.cpp:(.text+0x40): undefined reference to
cv :: imread (cv :: String const &, int) 'io.cpp :(. Text + 0xd4): référence non définie à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): référence non définie àcv::String::allocate(unsigned long)' CMakeFiles/cv_io.dir/io.cpp.o: In function
cv :: String :: ~ String () ': io.cpp :(. Text._ZN2cv6StringD2Ev [_ZN2cv6StringD5Ev] + 0x10): référence non définie àcv::String::deallocate()' CMakeFiles/cv_io.dir/io.cpp.o: In function
cv :: String :: operator = (cv :: String const &)': io.cpp :(. text. ZN2cv6StringaSERKS0 [ ZN2cv6StringaSERKS0] + 0x2c): référence non définie à `cv :: String :: deallocate () 'collect2: erreur: ld a renvoyé 1 état de sortie CMakeFiles/cv_io.dir/build.make: 121: la recette de la cible 'cv_io' a échoué make 2 : * [cv_io] Erreur 1 CMakeFiles/Makefile2: 67: la recette de la cible 'CMakeFiles/cv_io.dir/all' a échoué make 1 : * [CMakeFiles/cv_io.dir/all] Erreur 2 Makefile: 83: la recette de la cible "tous" a échoué: *** [tout] Erreur 2
Est-ce que quelqu'un sait comment résoudre ce problème? Je pense que le problème est que je ne relie toujours pas toutes les bibliothèques correctement dans le CMakeLists.txt
. De plus, j'ai trouvé n commentaire sous cet article mentionnant quelque chose de similaire à ce que je vis, mais je ne comprends pas la page contenant la solution à laquelle il fait référence. Je suis très nouveau sur OpenCV et CMake, donc j'espère que vous pourrez me fournir des instructions aussi explicites que possible. Je suis coincé là-dessus depuis toujours, donc toute aide est très appréciée! Merci beaucoup!
J'ai un travail CMakelists.txt
pour presque la même configuration que celle que vous décrivez, sauf que j'utilise un vieux Ubuntu 12.04 intimidant (ce n'est pas mon propre ordinateur).
Je crois que votre problème vient de cette ligne:
find_package(OpenCV REQUIRED)
Ce qui vous donne accès à OpenCV 2.4 de votre distribution. Ensuite, vous établissez une liaison avec la version 3.2.x installée manuellement. Des problèmes surviennent donc dès que l'interface d'une fonction que vous utilisez a changé entre les deux versions. Votre premier morceau de code exécuté par hasard, je pense.
Voici mon 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})
Si vous ne souhaitez pas valider dans votre référentiel le chemin codé en dur vers votre installation d'OpenCV 3.2, vous pouvez affiner ce CMakeList.txt
en modifiant le find_package
ligne vers:
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})
Il suffit ensuite de définir la variable OPENCV_INSTALL_DIR
avant d'exécuter cmake. Je le fais en l'exportant depuis mon .bashrc
En effet, vous établissez un lien avec la version par défaut d'OpenCV.
Reconfigurez votre projet en appelant CMake avec le bon chemin vers le fichier OpenCVConfig.cmake.
cmake /path/to/your/sources -DOpenCV_DIR=/home/ubuntu/opencv-3.2.0
Recherchez le fichier CMakeCache.txt
Dans votre répertoire de construction. Il contient des variables internes CMake, des chemins OpenCV sont également là.
En outre, il est incorrect de coder en dur les chemins d'accès. Utilisez include_directories(${OPENCV_INCLUDE_DIRS})
Et citation de OpenCVConfig.cmake
- OpenCV_LIB_DIR : The directory(es) where lib files are. Calling LINK_DIRECTORIES with this path is NOT needed.
Pendant que vous configurez les fichiers include pour utiliser les en-têtes OpenCV nouvellement installés, vous établissez une liaison avec l'opencv sur votre chemin système. La version est simplement stockée dans les en-têtes, c'est pourquoi elle génère la version attendue mais ne parvient pas à se lier. Essayez de définir la variable "OpenCV_DIR" à l'emplacement du fichier OpenCVConfig.cmake que vous souhaitez utiliser avant d'exécuter le module de recherche.
Voir la documentation de votre version de cmake ici . Notez les deux modes dans lesquels find_package peut être exécuté (mode Module ou Config).
Sauf si vous créez un lien vers des bibliothèques statiques, vous aurez toujours des problèmes pour exécuter votre bibliothèque/application. Pour résoudre ce problème, vous devrez ajouter les bibliothèques à votre LD_LIBRARY_PATH.