Символы OpenCV Undefined для архитектуры x86_64: ошибка

прежде чем это будет помечено как повторяющийся вопрос, пожалуйста, прочитайте конец. Спасибо, что посмотрели.

Я установил openCV с помощью home- brew.

Это были команды, которые я использовал:

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

Это ошибка, которую я получаю после попытки скомпилировать и запустить suing 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, моей ОС и т.д.) проблема. Я использую mac с ОС 10.9.4. И эти ответы мне не совсем поняли, что нужно изменить. Многие просто предложили одну строку кода, не сказав, куда должна идти линия. Я очень новичок в этих технологиях. Любая помощь будет очень благодарна!

Изменить: Марк Сетчелл помог с первой партией ошибок. Но теперь я получаю: g++ $(pkg-config --cflags --libs opencv) test.cpp -o Тест и. /Test

[3] 7187 dyld: библиотека не загружена: lib/libopencv_calib3d.2.4.dylib Ссылка из:/usr/local/Cellar/opencv/2.4.9/include/./Test Причина: изображение не найдено [2] Сделано g++ $(pkg-config --cflags --libs opencv) test.cpp -o Тест Trace/BPT trap: 5

brewdoctor дал мне это предупреждение: Предупреждение: в вашем подвале у вас есть разблокированные бочонки Если оставить неблокированные бочонки, это может привести к сбоям в работе и вызвать завихрения, зависящие от эти бочонки не могут работать должным образом после постройки. Запустите brew link на них:

opencv

Итак, я запустил ссылку brew --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

Ответы

Ответ 1

Вы получаете ошибки компоновщика. Я думаю, это потому, что вы не связываетесь с правильными библиотеками, которые требуются для 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

По сути, первое слово в каждой строке приведенного выше списка говорит вам об именах пакетов, о pkgconfig знает pkgconfig и это имя следует указывать при запуске таких команд, как

pkg-config --cflags --libs opencv4

Если ваша система немного перепутались, вы можете найти .pc файл pkgconfig используется следующим образом:

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

Ответ 2

Вы получаете эти ошибки, потому что вы используете методы OpenCV в вашем коде, которые не связаны с вашим проектом.

Пока вы включили только:

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

Но для запуска вашего кода вам нужно гораздо больше, чем эти две библиотеки 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. Каталог должен быть здесь:

/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. Запустите вашу программу

При повторной сборке программы у вас должно быть на одну ошибку меньше. И у 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"

Прежде чем сходить с ума по всем ошибкам, вы можете просто связать все библиотеки и посмотреть, правильно ли они собираются.

Ответ 3

Моя проблема была в том, что brew скомпилирован и связан с Xcode, и я использовал другую версию g++ из macports. Я просто добавил местоположение Xcode g++ в $PATH в моем файле .bash_profile и отменил привязку неверного двоичного файла g++ с помощью sudo port select --set gcc none. Вы можете найти местоположение Xcode g++, запустив xcodebuild -find g++, у меня был /Applications/Xcode.app/Contents/Developer/usr/bin/g++.