web-dev-qa-db-ja.com

同じコンピューターでOpenCVの複数のバージョンを実行する

私のコンピューターはUbuntu-16.04-LTSを実行しており、OpenCV-2.4.13が既にインストールされています。ただし、古いバージョンを削除せずに、OpenCV-3.2.0などのOpenCVの新しいバージョンの機能を使用したいと思います。

これまでにOpenCV-3.2.0をダウンロードし、コンパイルしてインストールしました。 OpenCVをコンパイルするためにCMakeを使用しているので、_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 to cv :: imread(cv :: String const&、int) 'io.cpp :(。text + 0xd4):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):cv::String::allocate(unsigned long)' CMakeFiles/cv_io.dir/io.cpp.o: In function cv :: String ::〜への未定義の参照String() ':io.cpp :(。text._ZN2cv6StringD2Ev [_ZN2cv6StringD5Ev] + 0x10):cv::String::deallocate()' CMakeFiles/cv_io.dir/io.cpp.o: In function cv :: String :: operator =(cv :: String const&)':io.cppへの未定義の参照:(。text。ZN2cv6StringaSERKS0[ZN2cv6StringaSERKS0] + 0x2c): `cv :: String :: deallocate()への未定義の参照'collect2:エラー:ldが1つの終了ステータスを返しましたCMakeFiles/cv_io.dir/build.make:121:ターゲット' cv_io 'のレシピがmakeに失敗しました 2* [ cv_io]エラー1 CMakeFiles/Makefile2:67:ターゲット 'CMakeFiles/cv_io.dir/all'のレシピが失敗したmake 1 :*[CMakeFiles/cv_io.dir /エラー2 Makefile:83:ターゲット 'all'のレシピがmakeに失敗しました:*** [all]エラー2

誰もこの問題を解決する方法を知っていますか?問題は、まだ_CMakeLists.txt_内のすべてのライブラリを適切にリンクしていないことだと思います。また、私は この記事の下のコメント が私が経験しているものに似た何かに言及しているのを見つけましたが、私は理解していません 解決策を含むページ それは参照しています。 私はOpenCVとCMakeが初めてなので、できる限り明示的な指示を提供していただければ幸いです。私は永遠にこれに固執しているので、どんな助けも大歓迎です!ありがとうございました!

18
Tony Tarng

恐ろしく古いUbuntu 12.04(自分のコンピューターではない)を実行していることを除けば、説明とほぼ同じ構成のCMakelists.txtが動作しています。

私はあなたの問題がこの行から来ると信じています:

find_package(OpenCV REQUIRED)

これにより、ディストリビューションのOpenCV 2.4にアクセスできます。次に、手動でインストールされた3.2.xバージョンに対してリンクしています。そのため、使用する関数のインターフェースが2つのバージョン間で変更されるとすぐに問題が発生します。あなたの最初のコードは偶然に実行されると思います。

これが私の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})

次に、cmakeを実行する前に変数OPENCV_INSTALL_DIRを定義する必要があります。私は.bashrcからエクスポートすることでそれを行います

7

実際、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.
_
1
wl2776

新しくインストールされたOpenCVヘッダーを使用するようにインクルードファイルを設定している間、システムパス上のopencvにリンクしています。バージョンはヘッダーに保存されているだけなので、期待されるバージョンを出力しているのにリンクできません。検索モジュールを実行する前に、使用するOpenCVConfig.cmakeファイルの場所に変数「OpenCV_DIR」を設定してみてください。

Cmake here のバージョンのドキュメントを参照してください。 find_packageを実行できる2つのモード(モジュールモードまたは構成モード)に注意してください。

静的ライブラリにリンクしていない限り、ライブラリ/アプリケーションの実行に問題があります。これを修正するには、ライブラリをLD_LIBRARY_PATHに追加する必要があります。

1
jhauris