【问题标题】:Including opencv in a py2app-generated app在 py2app 生成的应用程序中包含 opencv
【发布时间】:2011-11-10 18:23:21
【问题描述】:

我使用的是装有 OS 10.7.2 和 Apple 默认 python 2.7.1 的 mac。我通过源代码安装了 opencv 2.3.1,并且可以确认 import cv 在 python 中工作。我创建了一个最小的 python 脚本(保存为“cvTest.py”),顶部只有import cv,没有别的,然后我使用了py2app(通过终端命令py2applet --make-setup cvTest.py; python setup.py py2app)。当我将生成的独立应用程序移动到未安装 opencv 的另一台计算机(mac、OS 10.7.2)并尝试运行该应用程序时,它会崩溃,并通过 console.app 出现以下错误:

11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest: Traceback (most recent call last):
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:   File "/Users/ra/Downloads/cvTest.app/Contents/Resources/__boot__.py", line 103, in <module>
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:     _argv_emulation()
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:   File "/Users/ra/Downloads/cvTest.app/Contents/Resources/__boot__.py", line 101, in _argv_emulation
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:     _get_argvemulator().mainloop()
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:   File "/Users/ra/Downloads/cvTest.app/Contents/Resources/__boot__.py", line 40, in mainloop
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest:     stoptime = Evt.TickCount() + timeout
11-11-10 1:17:38.591 PM [0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest: AttributeError: 'module' object has no attribute 'TickCount'
11-11-10 1:17:38.661 PM cvTest: cvTest Error
11-11-10 1:17:39.888 PM com.apple.launchd.peruser.502: ([0x0-0xcb9cb9].org.pythonmac.unspecified.cvTest[49524]) Exited with code: 255

然后我创建了一个简单的 bash 脚本,让我可以深入了解独立应用程序并从终端运行应用程序的二进制文件:

#!/bin/bash
CMD=$0
PROGDIR=$(echo $CMD|perl -pe 's|/[^/]*$||')
cd "$PROGDIR"
"./cvTest.app/Contents/MacOS/cvTest"

执行此操作会产生以下错误:

Traceback (most recent call last):
  File "/Users/ra/Downloads/cvTest.app/Contents/Resources/__boot__.py", line 137, in <module>
    _run('cvTest.py')
  File "/Users/ra/Downloads/cvTest.app/Contents/Resources/__boot__.py", line 134, in _run
    execfile(path, globals(), globals())
  File "/Users/ra/Downloads/cvTest.app/Contents/Resources/cvTest.py", line 1, in <module>
    import cv
  File "cv.pyc", line 1, in <module>
ImportError: No module named cv2.cv
2011-11-10 13:18:26.239 cvTest[49578:707] cvTest Error

[Process completed]

那么,这里发生了什么?为什么我会收到错误消息,有什么方法可以将 opencv 与 py2app 创建的应用程序捆绑在一起,以便 import cv 工作?

【问题讨论】:

    标签: python opencv py2app


    【解决方案1】:

    说实话,我不确定。但我正在开发一个基于计算机视觉的开源项目(它包装 OpenCV)以及其他项目(http://www.simplecv.org)。我们遇到的一个问题是跨平台部署,因为我们需要一键式安装程序。

    我们尝试在 Windows 上使用 Innosetup 并遇到很多问题。我受够了,所以我开始自己写。基本上这个程序所做的是一个引导程序。您下载我们的 exe,运行它,然后它会拉入它需要的文件/库列表并开始安装它们。所以在我们的例子中,我们可以在安装了零库的机器上安装我们的软件。它做的第一件事就是安装 python,然后是 setuptools,然后是 opencv,等等。

    基本上,我作为开源发布的应用程序将尝试替代 innosetup 但跨平台。如果你想看到它现在(大约 85%)完成的样子,你可以在以下位置查看它: https://github.com/ingenuitas/SimpleCV/blob/installer/install/simplecv-installer.py

    我计划在完成后分叉这个项目,这样它就可以成为一个通用安装程序,您只需提供一个清单文件即可。 这是现有的清单: https://github.com/ingenuitas/SimpleCV/blob/installer/install/manifest.json

    【讨论】:

      【解决方案2】:

      问题在于 py2app 在包中构建了一个完全不同的 Python 发行版。该发行版应该是自包含的,因此它需要包含应用程序在运行时可能使用的所有库(包括 OpenCV)。不幸的是,py2app 似乎错过了 dist/helloworld.app/Contents/Resources/lib/python2.7/lib-dynload/ 中所需的 cv2.so 文件(请参阅http://pythonhosted.org/py2app/implementation.html)。

      OpenCV 的工作安装如下所示:

      bash-3.2$ ls -1 /usr/local/lib/python2.7/site-packages/cv*
      /usr/local/lib/python2.7/site-packages/cv.py
      /usr/local/lib/python2.7/site-packages/cv.pyc
      /usr/local/lib/python2.7/site-packages/cv2.so
      

      所以理论上,将 cv2.so 复制到 dist/helloworld.app/Contents/Resources/lib/python2.X/lib-dynload/ 应该可以解决问题。

      不幸的是,它引入了另一个问题:

      bash-3.2$ dist/main_wx.app/Contents/MacOS/main_wx 
      Segmentation fault: 11
      

      cv2.so 有大量需要包含的依赖项:

      bash-3.2$ otool -L /usr/local/Cellar/opencv/2.4.5/lib/python2.7/site-packages/cv2.so 
      /usr/local/Cellar/opencv/2.4.5/lib/python2.7/site-packages/cv2.so:
              /usr/local/lib/python2.7/site-packages/cv2.so (compatibility version 0.0.0, current version 0.0.0)
              /usr/local/opt/python/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.0)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_flann.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_imgproc.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_video.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_ml.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_highgui.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_features2d.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_calib3d.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_photo.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_objdetect.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_contrib.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_legacy.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_gpu.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_ocl.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/local/Cellar/opencv/2.4.5/lib/libopencv_nonfree.2.4.dylib (compatibility version 2.4.0, current version 2.4.5)
              /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
              /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL (compatibility version 1.0.0, current version 1.0.0)
              /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
              /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
      

      我不知道如何处理它们,但我有一种感觉,没有它们,任何事情都不会奏效。我将其留在这里,希望其他人可以使用它来找到解决方案。

      【讨论】:

        【解决方案3】:

        查找依赖项并将其添加到 py2app 包可以这样完成:

        import os, sys, glob
        
        frameworks = []
        opencvLibs = glob.glob(os.path.join(sys.exec_prefix, 'lib', 'libopencv*.2.4.dylib'))
        frameworks.extend(opencvLibs)
        
        setup(app=['myApp'],
            options=dict(py2app=dict(
               frameworks=frameworks,
               includes = ['cv2',.....],
               packages = [........],
               ....
               )
            )
        

        但不幸的是,这并不能完全解决问题。对我来说,看起来 cv2.so 已经编译为带有指向 @rpath/Python 的静态链接,但在您的 pyapp 包中,它需要一个相对链接,以便应用程序可以移动。 :-(

        【讨论】:

        • @rpath/Python 引用可以用install_name_tool 修复——只要您在应用程序中捆绑的 Python 版本与 OpenCV 库引用它的路径中的可用版本完全相同.
        猜你喜欢
        • 2012-08-13
        • 1970-01-01
        • 2011-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        相关资源
        最近更新 更多