使用 Xcode 5 和 Matlab R2013b 在 OS X 10.9 中编译 mexopencv

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19773916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:15:13  来源:igfitidea点击:

Compiling mexopencv in OS X 10.9 with Xcode 5 and Matlab R2013b

xcodematlabopencvmex

提问by Daniel Golden

I'm interested in using Kota Yamaguchi's mexopencv libraryon my system with the following specifications:

我有兴趣在我的系统上使用Kota Yamaguchi 的 mexopencv 库,其规格如下:

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

I git cloned the latest OpenCV revision using the command on the mexopencv web site; this is version 084838d62a25fcb3eec9f610abf91b167bc6c2f5 from Sat Jul 20 05:18:37 2013 -0700.

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

I ran Matlab's mex -setupcommand and then implemented this workaroundfrom Mathworks to use Xcode 5 as my mex compiler.

我运行了 Matlab 的mex -setup命令,然后从 Mathworks实现了这个解决方法,以使用 Xcode 5 作为我的 mex 编译器。

I added macports' pkg-config command to the path with the Matlab command setenv('PATH', [getenv('PATH') ':/opt/local/bin']);

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

Now, running mxopencv.make yields the following linker error message:

现在,运行 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

I'm not sure what to do at this point. Is it possible to build mexopencv on my system?

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

回答by Daniel Golden

I finally figured out my problem, the solution of which led to other problems, which I eventually was able to solve. So here's a complete step-by-step procedure of what I did to get mexopencv working on my system (some steps will be repeated from my original question).

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

  1. Get mexopencv from http://www.cs.sunysb.edu/~kyamagu/mexopencv/
  2. Implement the Mathworks workaroundto get the Matlab mex compiler working with Xcode 5
  3. Run mex -setupfrom within Matlab
  4. Modify the newly-created ~/.matlab/R2013b/mexopts.sh file as follows:

    1. Replace all references of "-lstdc++" with "-lc++"
    2. Add the following arguments to the CXXFLAGS variable: "-std=gnu++11 -stdlib=libc++". These two steps ensure that you're using C++11 instead of C++98 (thanks to this stack overflow post).
    3. You should have already replaced all instances of the text "10.7" with "10.8" from an earlier step
    4. Change the line

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

    to

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

    This ensures that the compiler does not search for OpenCV libraries in $TMW_ROOT/bin/$Archwhich, on my system, evaluates to /Applications/MATLAB_R2013b.app/bin/maci64. For whatever reason, libraries from an older version of OpenCV (2.4.2) come with Matlab and live in that folder (maybe they come with the Computer Vision System Toolbox). [Note: this step may not be necessary]

  5. Create a folder /Applications/MATLAB_R2013b.app/bin/maci64/libopencvand move all of the libopencv*.dylibfiles from /Applications/MATLAB_R2013b.app/bin/maci64into that folder. This prevents the linker from finding and accidentally linking to this older version of OpenCV.
  6. Add macports' pkg-config command to the Matlab path with the Matlab command setenv('PATH', [getenv('PATH') ':/opt/local/bin']);To avoid entering this command every time you start Matlab, you can add this to your startup.mfile. Mine lives in ~/Documents/MATLAB/startup.m.
  7. Make sure that you run mexopencv.make('clean', true);in Matlab to erase any prior failed attempts at compiling mexopencv
  8. Run mexopencv.makein Matlab; it should work properly (with some warnings) and in five minutes or so you will have a MEX-compiled version of OpenCV; congratulations! But you're not done yet.
  1. http://www.cs.sunysb.edu/~kyamagu/mexopencv/获取 mexopencv
  2. 实施Mathworks 解决方法以使 Matlab mex 编译器与 Xcode 5 配合使用
  3. mex -setup在 Matlab 中运行
  4. 修改新创建的~/.matlab/R2013b/mexopts.sh文件如下:

    1. 将“-lstdc++”的所有引用替换为“-lc++”
    2. 将以下参数添加到 CXXFLAGS 变量:“-std=gnu++11 -stdlib=libc++”。这两个步骤确保您使用的是 C++11 而不是 C++98(感谢这篇堆栈溢出帖子)。
    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"
    

    这确保编译器不会搜索 OpenCV 库$TMW_ROOT/bin/$Arch,在我的系统上,它的计算结果为/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命令将macports的pkg-config命令添加到Matlab路径中setenv('PATH', [getenv('PATH') ':/opt/local/bin']);为避免每次启动Matlab时都输入此命令,您可以将其添加到您的startup.m文件中。我住在~/Documents/MATLAB/startup.m.
  7. 确保您mexopencv.make('clean', true);在 Matlab 中运行以清除任何先前在编译 mexopencv 时失败的尝试
  8. mexopencv.make在 Matlab 中运行;它应该可以正常工作(有一些警告),大约五分钟后,您将拥有一个 MEX 编译版本的 OpenCV;恭喜!但你还没有完成。

I tried out my installation of OpenCV with a simple one-liner test:

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

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

When I attempted to run it at this point, I got the following error message:

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

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

The problem is that Matlab has its own version of some macports-installed libraries, contained in /Applications/MATLAB_R2013b.app/bin/maci64, that are different from the ones in /opt/local/lib. By default, Matlab tries to dynamically link its own versions of the libraries, which are not the versions that OpenCV expects, so the program doesn't run.

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

The solution is suggested in the README.markdownfile included with mexopencv. You need to tell Matlab not to use its own version of the shared libraries and to instead use the versions from /opt/local/lib.

README.markdownmexopencv 随附的文件中建议了解决方案。您需要告诉 Matlab 不要使用自己的共享库版本,而是使用/opt/local/lib.

You can do this one of two ways. First, try to run your program and note the name of the library that yields an error. Then, either:

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

  1. Find the library file in /Applications/MATLAB_R2013b.app/bin/maci64 and rename or move it. E.g., rename /Applications/MATLAB_R2013b.app/bin/maci64/libtiff.5.dylibto /Applications/MATLAB_R2013b.app/bin/maci64/libtiff.5.dylib.bak. This might have unintended consequences if other Matlab functionality depends on that library. You shouldn't need to do anything else in order for OpenCV to find the correct library in /opt/local/lib.
  2. Close Matlab and start it from the command line by first setting the DYLD_INSERT_LIBRARIESenvironment variable, like:

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

    In my case, after I solved the problem with libtiff.5.dylib, I also had a problem with libfreetype.6.dylib, so I added that to the DYLD_INSERT_LIBRARIESvariable, like:

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

  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 &

    就我而言,在我用 解决了问题后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 &

Then try to run your program again. If you get another library version error, keep iterating and either renaming/moving libraries from /Applications/MATLAB_R2013b.app/bin/maci64or adding the correct library paths to the DYLD_INSERT_LIBRARIESvariable. Eventually, it should work!

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

After I followed all these steps, I was able to run my Matlab command successfully:

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

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

Let me know if these steps did or didn't work for you, and whether I skipped any steps or made anything more complicated than it had to be.

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

I hope this helps someone! I spent several days combing the Internet and bothering Kota to finally arrive at the correct solution.

我希望这可以帮助别人!我花了几天时间在网上梳理和打扰Kota,终于得出了正确的解决方案。