在py2app生成的应用程序中包含opencv

问题描述:

我使用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提供以下错误:在py2app生成的应用程序中包含opencv

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有效?

说实话我不确定。但我正在开发一个基于计算机视觉的开源项目(它封装了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

问题是,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 /内容/资源/ lib中/ python2.X/LIB-dynload /应该解决问题。

不幸的是,它带来了另一个问题:

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

CV2。所以有一吨需要包括的依赖关系:

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) 

我不知道如何处理它们,但我有一种感觉,没有他们,没有什么工作。我希望别人可以用它来找到解决方案。

查找并添加依赖于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包中它需要一个相对链接,以便应用程序可以移动。 :-(

+0

只要您在应用程序中绑定的Python版本与OpenCV库引用它的路径中可用的版本完全相同,就可以使用'install_name_tool'修复@ rpath/Python参考。 – mz2