【问题标题】:Compiling mexopencv in OS X 10.9 with Xcode 5 and Matlab R2013b使用 Xcode 5 和 Matlab R2013b 在 OS X 10.9 中编译 mexopencv
【发布时间】:2026-02-09 03:35:01
【问题描述】:

我有兴趣在我的系统上使用 Kota Yamaguchi's mexopencv library 并具有以下规格:

  • OS X 10.9(小牛队)
  • Xcode 5
  • Matlab 2013b
  • OpenCV 通过 macports 安装到 /opt/local/include/{opencv,opencv2} 和 /opt/local/lib

我使用 mexopencv 网站上的命令克隆了最新的 OpenCV 版本;这是 2013 年 7 月 20 日星期六 05:18:37 -0700 的版本 084838d62a25fcb3eec9f610abf91b167bc6c2f5。

我运行 Matlab 的 mex -setup 命令,然后从 Mathworks 实现 this workaround 以使用 Xcode 5 作为我的 mex 编译器。

我用matlab命令setenv('PATH', [getenv('PATH') ':/opt/local/bin']);将macports的pkg-config命令添加到路径中

现在,运行 mxopencv.make 会产生以下链接器错误消息:

Undefined symbols for architecture x86_64:
  "cv::merge(std::vector<cv::Mat, std::allocator<cv::Mat> > const&, cv::_OutputArray const&)", referenced from:
      MxArray::toMat(int, bool) const in libMxArray.a(MxArray.o)
  "cv::split(cv::Mat const&, std::vector<cv::Mat, std::allocator<cv::Mat> >&)", referenced from:
      MxArray::MxArray(cv::Mat const&, mxClassID, bool) in libMxArray.a(MxArray.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

    mex: link of ' "+cv/CamShift.mexmaci64"' failed.

make: *** [+cv/CamShift.mexmaci64] Error 255

我现在不知道该怎么做。是否可以在我的系统上构建 mexopencv?

【问题讨论】:

  • Mac 的文档中没有任何内容。但是如果make去CamShift,这意味着你可以编译之前的所有其他文件吗?您是否尝试删除 CamShift.cpp ?
  • 看看this
  • @AlexandreBizeau,如果我删除 CamShift,我只会在下一个文件(即 Canny)上收到相同的错误消息。您提到的另一篇文章是在 Xcode 中构建 OpenCV,而不是使用 Matlab 的 mex 命令构建 mexopencv。
  • 我确实注意到,如果我关注Mathworks' steps for building using Xcode 5,这涉及修改我的 mexopts.sh 副本,而是将目标设置为 OS X 10.9 而不是 10.8,我会收到更多错误。所以也许 mexopencv 中的某些东西是为 OS X 10.7 编译的,与我的 10.8 目标不兼容?
  • 这是我的确切问题。我们可能是唯一有这个问题的人。我想知道是否遵循所有 Matlab 设置部分可以让我编译/链接 gitHub 上 openCV 开发仓库中包含的绑定。

标签: xcode matlab opencv mex


【解决方案1】:

我终于弄清楚了我的问题,解决了这个问题,导致了其他问题,我最终能够解决这些问题。因此,这是一个完整的分步过程,说明我为使 mexopencv 在我的系统上工作所做的工作(某些步骤将从我的原始问题中重复)。

  1. http://www.cs.sunysb.edu/~kyamagu/mexopencv/ 获取 mexopencv
  2. 实现 Mathworks workaround 以使 Matlab mex 编译器与 Xcode 5 一起工作
  3. 在 Matlab 中运行 mex -setup
  4. 将新建的~/.matlab/R2013b/mexopts.sh文件修改如下:

    1. 将“-lstdc++”的所有引用替换为“-lc++”
    2. 将以下参数添加到 CXXFLAGS 变量:“-std=gnu++11 -stdlib=libc++”。这两个步骤可确保您使用的是 C++11 而不是 C++98(感谢 this stack overflow post)。
    3. 您应该已经在前面的步骤中将文本“10.7”的所有实例替换为“10.8”
    4. 换行

    MLIBS="-L$TMW_ROOT/bin/$Arch -lmx -lmex -lmat"

    MLIBS="$TMW_ROOT/bin/$Arch/libmx.dylib $TMW_ROOT/bin/$Arch/libmex.dylib $TMW_ROOT/bin/$Arch/libmat.dylib"
    

    这可确保编译器不会在 $TMW_ROOT/bin/$Arch 中搜索 OpenCV 库,在我的系统上,该库的计算结果为 /Applications/MATLAB_R2013b.app/bin/maci64。无论出于何种原因,来自旧版本 OpenCV (2.4.2) 的库随 Matlab 一起提供并存在于该文件夹中(也许它们随计算机视觉系统工具箱一起提供)。 [注意:此步骤可能不是必需的]

  5. 创建一个文件夹/Applications/MATLAB_R2013b.app/bin/maci64/libopencv 并将所有libopencv*.dylib 文件从/Applications/MATLAB_R2013b.app/bin/maci64 移到该文件夹​​中。这可以防止链接器找到并意外链接到这个旧版本的 OpenCV。
  6. 使用 Matlab 命令setenv('PATH', [getenv('PATH') ':/opt/local/bin']); 将 macports 的 pkg-config 命令添加到 Matlab 路径为避免每次启动 Matlab 时都输入此命令,可以将其添加到 startup.m 文件中。我住在~/Documents/MATLAB/startup.m
  7. 确保在 Matlab 中运行 mexopencv.make('clean', true); 以清除之前编译 mexopencv 的任何失败尝试
  8. 在 Matlab 中运行mexopencv.make;它应该可以正常工作(带有一些警告),并且在五分钟左右您将拥有一个 MEX 编译版本的 OpenCV;恭喜!但你还没有完成。

我通过一个简单的单行测试尝试了我的 OpenCV 安装:

imshow(cv.Canny(rgb2gray(imread('peppers.png')), [10 100]))

此时我尝试运行它时,收到以下错误消息:

>> imshow(cv.Canny(rgb2gray(imread('peppers.png')), [10 100]));
Error using cv.Canny
Invalid MEX-file '/Users/dgolden/software/cpp/mexopencv/+cv/Canny.mexmaci64': dlopen(/Users/dgolden/software/cpp/mexopencv/+cv/Canny.mexmaci64, 6): Library not loaded:
/opt/local/lib/libtiff.5.dylib
  Referenced from: /opt/local/lib/libopencv_highgui.2.4.dylib
  Reason: Incompatible library version: libopencv_highgui.2.4.dylib requires version 8.0.0 or later, but libtiff.5.dylib provides version 6.0.0

问题在于 Matlab 有自己版本的一些 macports 安装的库,包含在 /Applications/MATLAB_R2013b.app/bin/maci64 中,与 /opt/local/lib 中的不同。默认情况下,Matlab 会尝试动态链接它自己的库版本,这不是 OpenCV 期望的版本,因此程序不会运行。

在 mexopencv 包含的 README.markdown 文件中建议了该解决方案。您需要告诉 Matlab 不要使用自己的共享库版本,而是使用来自/opt/local/lib 的版本。

您可以通过以下两种方式之一进行操作。首先,尝试运行您的程序并记下产生错误的库的名称。然后,要么:

  1. 在 /Applications/MATLAB_R2013b.app/bin/maci64 中找到库文件并重命名或移动它。例如,将 /Applications/MATLAB_R2013b.app/bin/maci64/libtiff.5.dylib 重命名为 /Applications/MATLAB_R2013b.app/bin/maci64/libtiff.5.dylib.bak。如果其他 Matlab 功能依赖于该库,这可能会产生意想不到的后果。为了让 OpenCV 在 /opt/local/lib 中找到正确的库,您无需执行任何其他操作。
  2. 关闭 Matlab 并从命令行启动它,首先设置DYLD_INSERT_LIBRARIES 环境变量,如:

    DYLD_INSERT_LIBRARIES=/opt/local/lib/libtiff.5.dylib /Applications/MATLAB_R2013b.app/bin/matlab &amp;

    就我而言,在我用libtiff.5.dylib 解决了问题后,我也遇到了libfreetype.6.dylib 的问题,所以我将它添加到DYLD_INSERT_LIBRARIES 变量中,例如:

    DYLD_INSERT_LIBRARIES=/opt/local/lib/libtiff.5.dylib:/opt/local/lib/libfreetype.6.dylib /Applications/MATLAB_R2013b.app/bin/matlab &amp;

然后尝试再次运行您的程序。如果您遇到另一个库版本错误,请继续迭代并从 /Applications/MATLAB_R2013b.app/bin/maci64 重命名/移动库或将正确的库路径添加到 DYLD_INSERT_LIBRARIES 变量。最终,它应该可以工作了!

在完成所有这些步骤后,我能够成功运行我的 Matlab 命令:

imshow(cv.Canny(rgb2gray(imread('peppers.png')), [10 100]))

让我知道这些步骤是否适合您,以及我是否跳过任何​​步骤或使任何事情变得更复杂。

我希望这对某人有所帮助!我花了几天时间在互联网上梳理并困扰 Kota 最终得出了正确的解决方案。

【讨论】:

  • 运行 mexopencv.make 时出现错误; In file included from src/MxArray.cpp:6: include/MxArray.hpp:14:10: fatal error: 'opencv2/opencv.hpp' file not found #include "opencv2/opencv.hpp 此处有关错误的更多信息:pastie.org/private/wstqunwnwqhfm547qxlkw
  • 搜索了一下问题,我找到了github.com/kyamagu/mexopencv/issues/90。在运行步骤 1-5 后,以通常的方式从命令行运行 make 似乎对我有用。如果我不报告,它对我有用。