在xcode 4.5.1上链接OpenCV 2.4.2库

13

我已经按照这里的指导使用macports安装了opencv:Compile OpenCV (2.3.1+) for OS X Lion / Mountain Lion with Xcode

我还在stackexchange和谷歌上搜索并尝试了所有其他变体,但这似乎是最接近的。

它对一些东西似乎有效,但对于附带2.4.2的示例代码则无效。请注意,我已将ALL opencv 2.4.2 dylibs Link Binary with Libraries添加到其中。

例如,以下内容将编译并运行:

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

int main ( int argc, char **argv )
{
    cvNamedWindow( "My Window", 1 );
    IplImage *img = cvCreateImage( cvSize( 640, 480 ), IPL_DEPTH_8U, 1 );
    CvFont font;
    double hScale = 1.0;
    double vScale = 1.0;
    int lineWidth = 1;
    cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,
           hScale, vScale, 0, lineWidth );
    cvPutText( img, "Hello World!", cvPoint( 200, 400 ), &font,
          cvScalar( 255, 255, 0 ) );
    cvShowImage( "My Window", img );
    cvWaitKey();
    return 0;
}

然而,当我尝试构建任何一个示例,比如以下的display_image.cpp示例,我会收到链接错误。

-不起作用-

 #include <stdio.h>
 #include <iostream>
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/flann/miniflann.hpp"

 using namespace cv; // all the new API is put into "cv" namespace. Export its content
 using namespace std;
 using namespace cv::flann;

static void help()
{
    cout <<
    "\nThis program shows how to use cv::Mat and IplImages converting back and forth.\n"
    "It shows reading of images, converting to planes and merging back, color conversion\n"
    "and also iterating through pixels.\n"
    "Call:\n"
    "./image [image-name Default: lena.jpg]\n" << endl;
}

int main(int argc, char *argv[])
{
    help();
    const char* imagename = argc > 1 ? argv[1] : "lena.jpg";
    Mat img = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function
    if(img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagename);
        return -1;
    }
    if( !img.data ) // check if the image has been loaded properly
        return -1;

    Mat img_yuv;
    cvtColor(img, img_yuv, CV_BGR2YCrCb); // convert image to YUV color space. The output image will be created automatically

    vector<Mat> planes; // Vector is template vector class, similar to STL's vector. It can store matrices too.
    split(img_yuv, planes); // split the image into separate color planes

    imshow("image with grain", img);

    waitKey();

    return 0;

}

我遇到了以下错误:

Undefined symbols for architecture x86_64:
 "cv::split(cv::Mat const&, std::__1::vector<cv::Mat, std::__1::allocator<cv::Mat> >&)", referenced from:
  _main in main1.o
 "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
  _main in main1.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 main1.o
 ld: symbol(s) not found for architecture x86_64
 clang: error: linker command failed with exit code 1 (use -v to see invocation)

有什么办法可以解决这个问题吗?


Anthony和Marco在下面给出了正确的答案。这是一种经历过后,你就会永远知道的事情。你应该接受一个答案来帮助未来的访问者。 - jww
3个回答

42

我遇到了同样的问题。 在Xcode 4.5中,构建设置默认值似乎有所不同。

在“构建设置”-> Apple LLVM编译器4.1 - 语言 >

C++标准库:= libc++(LLVM ...)更改为libstdc++(GNU C++ ...)。


1
它对我产生了相反的效果:我将标准库从GNU更改为LLVM。 - Valeriy Van
1
@BRabbit27,“nm”命令显示libc++与libstdc++具有不同的符号命名约定。因此,我们必须选择与OpenCV编译时相同的C++库,否则链接器将无法解析符号。这里是一个屏幕截图,显示libc++和libstdc++之间的不同命名→ [链接](http://i.stack.imgur.com/Mnexn.png) - Shigerello
我也遇到了这个问题。我的名称修饰与BRappit27的截图所示不匹配。但是我不明白使用的C++库与我的程序二进制文件如何链接到OpenCV库有任何关系。难道不是编译器标志将确定名称修饰吗?能否有人解释一下? - Steve
我还想要更深入的解释。我对名称修饰和相关内容一无所知。"nm"命令是什么?难道创建库时使用的编译器不应该与Xcode默认使用的编译器相同吗? - BRabbit27
我知道这已经很老了,但它仍然是一个问题,所以我会详细说明 - 问题在于C++名称重载需要将函数参数的类型嵌入到重载名称中。而GNU和LLVM C++标准库对std::string有不同的类型(可能还有其他类型)。因此,任何具有std::string参数的函数都将以不同的重载名称结束。cv::imshow就是这样一个函数,因此链接器正在寻找一个具有一个重载名称的函数,但higui中的版本具有不同的名称。 - JoshG79
显示剩余2条评论

4
很可能OpenCV没有使用C++11设置进行编译,而程序却使用了。 将工具的构建设置为不带C++11开关(即-std=c++11 -stdlib=libc++)。

0
尝试手动添加端口放置所有dylibs的目录(如果我没有弄错的话,是/opt/local/lib)到“构建设置->库搜索路径”中。这应该可以解决链接问题。

谢谢,但我已经做过了。没有它,我会得到一个不同的错误:ld: 找不到库 -lopencv_calib3d.2.4.2 clang: 错误: 链接器命令失败,退出代码为1(使用-v查看调用) - glerg

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