OpenCV未定义符号架构x86_64:错误

25

在此之前,如果您认为这是一个重复的问题,请阅读结尾。感谢您的关注。

我使用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)

我在stackoverflow上找到类似的问题,但没有使用homebrew,而且我不确定问题有多么紧急(关于OpenCV、我的操作系统等更新和更改)。我正在使用运行OS 10.9.4的Mac。此外,那些答案并没有很清楚地告诉我应该改变什么,许多人只是建议更改一行代码,而不说明该行代码应该放在哪里。我对这些技术非常陌生,任何帮助都将是极好的,谢谢!

编辑: 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 原因:找不到图像 [2] Done g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test Trace/BPT trap: 5

brewdoctor给出了以下警告: 警告:您在Cellar中有未链接的kegs。 留下未链接的kegs可能会导致构建问题,并使依赖于这些kegs的软件无法正确运行。在这些kegs上运行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

1
你是如何尝试编译它的?用了什么命令? - Mark Setchell
@MarkSetchell,使用以下命令编译test.cpp文件:g++ test.cpp -o test。谢谢!我已将此添加到我的问题中。 - Bren
1
尝试这个... g++ @pkg-config --cflags --libs opencv@ test.cpp -o Test。将@符号替换为键盘左上角附近的反引号。 - Mark Setchell
@MarkSetchell 我得到了这个错误:clang: error: 不支持选项 '--cflags' clang: error: 不支持选项 '--libs' clang: error: 没有找到文件或目录:'pkg-config' - Bren
我很享受尝试输入这个命令,试试这个:g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test - Mark Setchell
显示剩余3条评论
3个回答

45

你遇到了链接错误。我认为这是因为你没有链接 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 知道哪些包的名称,这也是您在运行像以下命令时应该指定的名称。
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

1
你可能正在运行 /bin/test。请确保你运行的是 ./Test 或者 ./test - Mark Setchell
1
嗯,大部分似乎都可以工作。得到这个:g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test & ./Test [3] 7187 dyld: Library not loaded: lib/libopencv_calib3d.2.4.dylib   Referred from:/usr/local/Cellar/opencv/2.4.9/include/./Test   Reason:找不到图像。 [2] Done g++ $(pkg-config --cflags --libs opencv) test.cpp -o Test Trace/BPT trap: 5.不过,在同一目录下有一张图片。 - Bren
在OSX上查看图片的简单方法是输入open imagename,例如:open my_image_copy.png - Mark Setchell
我猜你在那个目录下有一个名为my_image.jpg的文件,以便它能够打开? - Mark Setchell
非常感谢您的帮助,但我现在必须离开。所以我暂时无法继续处理这个问题。 - Bren
显示剩余2条评论

15

您之所以会收到这些错误,是因为您在代码中使用了未链接到项目的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版本。)

为了解决这个错误,你需要执行两个步骤:

  1. 将该库添加到你的项目中: 右键单击你的项目文件。点击“添加文件到blabla”,然后浏览到你的OpenCV目录。这些库应位于

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

注意!这可能取决于你如何安装OpenCV!如果你使用Homebrew安装它,则目录应该在这里:

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

添加库到OpenCV项目中的图片

选择以下库(libopencv_imgcodecs.3.1.0.dylib),并将其添加到您的项目中:

选择OpenCV库的图片

将库添加到您的项目后,它应该出现在左侧列表中。请务必仔细检查是否选择了正确的库。它们中有些名称非常相似!

  1. 在C++文件中引用这个库

就像这样完成了:

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

现在您应该继续将新的库包含进来:

#include "opencv2/imgcodecs/imgcodecs.hpp"

图片:包含新的OpenCV库

  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"

在着手处理所有错误之前,您可以尝试链接所有库并查看是否可以正确构建。


1
我的问题是brew使用Xcode编译和链接,而我正在使用来自macports的不同版本的g++。我只需将Xcode g++位置添加到$PATH变量中的.bash_profile文件中,并使用sudo port select --set gcc none取消链接错误的g++二进制文件即可。您可以通过运行xcodebuild -find g++找到Xcode g++位置,我的位置是/Applications/Xcode.app/Contents/Developer/usr/bin/g++

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接