web-dev-qa-db-ja.com

アーキテクチャx86_64のOpenCV未定義シンボル:エラー

これが繰り返し質問として報告される前に、最後を読んでください。見てくれてありがとう。

Home-brewを使用してopenCVをセットアップします。

これらは私が使用したコマンドでした:

brew tap homebrew/science
brew install opencv

オンラインで見つけた次の簡単なファイルを使用して、セットアップをテストしています。

// Example showing how to read and write images
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main(int argc, char** argv)
{   
    // Load an image from file - change this based on your image name
    Mat img = imread("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);

    if(img.empty())
    {
        fprintf(stderr, "failed to load input image\n");
        return -1;
    }

    // this is just to show, that you won't have to pre-alloc
    // result-images with c++ any more..
    Mat gray;
    cvtColor(img,gray,CV_BGR2GRAY);

    // Write the image to a file with a different name,
    // using a different image format -- .png instead of .jpg
    if( ! imwrite("my_image_copy.png", img) )
    {
        fprintf(stderr, "failed to write image file\n");
    }

    // no need to release anything with c++ !   
    return 0;
}

これは、g++ test.cpp -o testを呼び出してコンパイルして実行しようとした後に得られるエラーです。

Undefined symbols for architecture x86_64:
  "cv::_InputArray::_InputArray(cv::Mat const&)", referenced from:
      _main in test-41a30e.o
  "cv::namedWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      _main in test-41a30e.o
  "cv::destroyWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      _main in test-41a30e.o
  "cv::Mat::deallocate()", referenced from:
      cv::Mat::release() in test-41a30e.o
  "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      _main in test-41a30e.o
  "cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&)", referenced from:
      _main in test-41a30e.o
  "cv::waitKey(int)", referenced from:
      _main in test-41a30e.o
  "cv::fastFree(void*)", referenced from:
      cv::Mat::~Mat() in test-41a30e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

私はスタックオーバーフローで同様の問題を見つけましたが、homebrewを使用していないため、問題がどのくらい時間に敏感かはわかりません(OpenCV、私のOSなどの更新に関して)。 10.9.4 OSでMacを使用しています。また、これらの回答は、何を変更する必要があるかについて私には本当に明確ではありませんでした。多くの人は、行がどこに行くべきかを言わずに1行のコードを提案しただけです。私はこれらの技術を非常に初心者です。どんな助けでも大歓迎です!

編集:Mark Setchellが最初のエラーのバッチを助けました。しかし、私は今取得しています:g ++ $(pkg-config --cflags --libs opencv)test.cpp -o Test&./Test

[3] 7187 dyld:ライブラリがロードされていません:lib/libopencv_calib3d.2.4.dylib参照元:/usr/local/Cellar/opencv/2.4.9/include/./Test理由:image not found [2] Done g ++ $( pkg-config --cflags --libs opencv)test.cpp -oテストトレース/ BPTトラップ:5

brewdoctorは私にこの警告を与えました:警告:セラーにリンクされていない樽がありますこれらに対してbrew linkを実行します。

opencv

そこでbrew link --overwrite opencvを実行しましたが、次のようになりました:

Linking /usr/local/Cellar/opencv/2.4.9... 
Error: Could not symlink include/opencv/cv.h

brew link opencvが与えたため、上書きが必要でした

Linking /usr/local/Cellar/opencv/2.4.9... 
Error: Could not symlink include/opencv/cv.h
Target /usr/local/include/opencv/cv.h
already exists. You may want to remove it:
  rm /usr/local/include/opencv/cv.h
21
Bren

リンカーエラーが発生しています。 opencvが必要とする正しいライブラリとリンクしていないからだと思います。

正しいライブラリを取得する最も簡単な方法はpkg-configを使用することです。したがって、次のことをお勧めします。

brew install pkg-config

その後、opencvを再インストールする必要がある場合があります

brew reinstall opencv

または多分

brew uninstall opencv
brew install opencv

その後、次のことができるはずです。

g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test 

走れます

pkg-config --cflags --libs opencv4

g++コンパイラの出力を確認するには、ライブラリとヘッダーファイルの場所をコンパイラに伝えます。私のシステムでは、これを出力します:

pkg-config --cflags --libs opencv4

-I/usr/local/Cellar/opencv/2.4.12_2/include/opencv \
-I/usr/local/Cellar/opencv/2.4.12_2/include \
-L/usr/local/Cellar/opencv/2.4.12_2/lib \
-lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab

pkgconfigに慣れていない場合は、次のように、知っているすべてのパッケージを教えてもらうことができます。

pkg-config --list-all

私のシステムは次のような出力を提供します:

libzmq                              libzmq - 0MQ c++ library
gio-unix-2.0                        GIO unix specific APIs - unix specific headers for glib I/O library
glibmm-2.4                          glibmm - C++ wrapper for GLib
libpostproc                         libpostproc - FFmpeg postprocessing library
libgsf-1                            libgsf-1 - A library for reading and writing structured files (eg MS OLE and Zip)
gobject-introspection-no-export-1.0 gobject-introspection - GObject Introspection
libtasn1                            libtasn1 - Library for ASN.1 and DER manipulation
libusb-1.0                          libusb-1.0 - C API for USB device access from Linux, Mac OS X, Windows and OpenBSD/NetBSD userspace
gio-2.0                             GIO - glib I/O library
libusb                              libusb - USB access library (libusb-1.0 compat wrapper)
libecpg_compat                      libecpg_compat - PostgreSQL libecpg_compat library
QtNetwork                           Qtnetwork - Qtnetwork Library
opencv4                              OpenCV - Open Source Computer Vision Library

基本的に、上記のリストの各行の最初のWordは、pkgconfigが知っているパッケージの名前を示します。これは、次のようなコマンドを実行するときに指定する名前です

pkg-config --cflags --libs opencv4

システムが少し混乱している場合は、pkgconfigが次のように使用する.pcファイルを見つけることができます。

find /usr/local/Cellar -name \*.pc

または

find /usr/local/Cellar -name \*.pc | grep -i opencv

/usr/local/Cellar/opencv3/3.1.0_3/lib/pkgconfig/opencv.pc

そして、次のように構成ファイルを直接使用します。

pkg-config --cflags --libs /usr/local/Cellar/opencv3/3.1.0_3/lib/pkgconfig/opencv.pc 

すべてが正しくコンパイルされたら、次のコマンドで実行できます。

./test
38
Mark Setchell

プロジェクトにリンクされていないコードでOpenCVメソッドを使用しているため、これらのエラーが発生しています。

これまでに含まれているのは次のもののみです。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

しかし、コードを実行するには、これら2つのOpenCVライブラリよりもはるかに多くが必要です。たとえば、XCODEでプロジェクトをビルドしようとすると、次のエラーが発生します。

Undefined symbols for architecture x86_64:
  "cv::imread(cv::String const&, int)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

エラーのこの部分に対応します。

...  "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      _main in test-41a30e.o  ...

これは、XCODEがコード内で次の関数を実行しようとしているために発生します。

Mat img = imread("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);

しかし、これを実装した方法では、imread()が何であるかはわかりません。なぜなら、への参照はopencvライブラリがありません!この特定の問題を解決するライブラリは次のとおりです。

libopencv_imgcodecs.3.1.0.dylib

(もちろん、バージョンは、使用しているOpenCVのバージョンに依存します。)

この特定のエラーを解決するには、2つの手順を実行する必要があります。

  1. ライブラリをプロジェクトに追加します。プロジェクトファイルを右クリックします。 [blablaにファイルを追加]をクリックして、OpenCVディレクトリを参照します。ライブラリは次の場所に配置する必要があります

/Users/YOURNAME/YOURFOLDER/opencv-3.1.0/build/lib

注意!これは、OpenCVのインストール方法によって異なります。 Homebrewを使用してインストールした場合、ディレクトリshoulbは次の場所にあります。

/usr/local/Cellar/opencv/2.4.9/lib

Picture: Add library to OpenCV Project.

次のライブラリ(libopencv_imgcodecs.3.1.0.dylib)を選択し、プロジェクトに追加します。

Picture: Pick the OpenCV Library

ライブラリをプロジェクトに追加すると、左側のリストに表示されます。 適切なライブラリを選択したことを再確認してください。それらのいくつかは非常に似た名前を持っています!

  1. ライブラリをC++ファイルに含める

あなたがそれをやったように:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

次に、新しいライブラリも含めて含める必要があります。

#include "opencv2/imgcodecs/imgcodecs.hpp"

Picture: Include the new OpenCV Library

  1. プログラムを実行する

プログラムを再度ビルドすると、エラーが1つ少なくなります。また、XCODEの実行に問題はないはずですcv :: imread

エラーがたくさんあるので、プログラムを正常にビルドするために必要なライブラリーを確認してください。

これらのライブラリは非常に一般的であるため、リンクすることをお勧めします。

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

すべてのエラーに夢中になる前に、すべてのライブラリをリンクして、正しくビルドされるかどうかを確認するだけです。

9
Kevin Katzke

私の問題は、brewがコンパイルされてXcodeとリンクされ、macportsとは異なるバージョンのg ++​​を使用していたことです。 Xcode g ++の場所を$PATHファイルの.bash_profile変数に追加し、Sudo port select --set gcc noneで間違ったg ++バイナリのリンクを解除しました。 Xcode g ++の場所を見つけるには、xcodebuild -find g++を実行します。私のものは/Applications/Xcode.app/Contents/Developer/usr/bin/g++でした。

0
bmsmith