python: OpenCV根目录

8 投票
5 回答
19701 浏览
提问于 2025-04-17 18:01

我正在使用OpenCV来做各种物体检测,但我发现写出可以在不同设备上运行的代码很困难。

比如说,要在一台通过homebrew安装了OpenCV的Mac上加载一个人脸检测器,我需要写:

haar=cv.Load('/usr/local/Cellar/opencv/2.4.2/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml')

这样写并不方便;如果我想换到另一台机器,我就得找另一个绝对路径,然后修改这段代码。

有没有什么变量可以保存OpenCV的根目录?这样我就可以写成:

haar=cv.Load(os.path.join(OpenCVRoot, "haarcascades", 
                          "haarcascade_frontalface_default.xml"))

更新:看起来这不仅是我一个人的问题;OpenCV的文档也有这个问题。文档里有以下这个坏掉的示例代码:

>>> import cv
>>> image = cv.LoadImageM("lena.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
>>> cascade = cv.Load("../../data/haarcascades/haarcascade_frontalface_alt.xml")
>>> print cv.HaarDetectObjects(image, cascade, cv.CreateMemStorage(0), 1.2, 2, 0, (20, 20))
[((217, 203, 169, 169), 24)]

如果有办法知道像lena.jpg和预训练分类器是安装在哪里的,那就简单多了。

来源:http://opencv.willowgarage.com/documentation/python/objdetect_cascade_classification.html(获取于2013年3月5日)

5 个回答

0

我也遇到过类似的问题,这真让人烦。

解决这种可移植性问题的一个方法是使用配置文件。在你的情况下,可以创建一个文件叫做 ~/.myprojectrc,这个文件可以包含:

[cv]
cvroot = '/usr/local/Cellar/opencv/2.4.2/share/OpenCV/`

这种格式的文件可以被 ConfigParser 对象读取,使用起来大概是这样的:

import ConfigParser
import os
CONFIG = ConfigParser.ConfigParser()
config_path = os.path.join(os.path.expanduser('~'), '.myprojectrc')
if not os.path.exists(config_path):
    raise Exception('You need to make a "~/.myprojectrc" file with your cv path or something')
CONFIG.read(config_path)

...

cv_root = CONFIG.get('cv', 'cvroot')

这样一来,当其他人在不同的机器上使用这段代码时,他们就不需要修改任何代码,只需创建一个包含 opencv 路径的配置文件,就能得到一个清晰的错误提示,告诉他们该怎么做。

2

看起来很难有一个可以在不同时间和不同平台上都能使用的统一机制,不过还是有一些进展。我不太确定是哪个版本开始引入的,但在4.0版本中是有这个功能的:

cv2.data.haarcascades - 这是一个指向目录的字符串,比如:

>>> import cv2
>>> cv2.data
<module 'cv2.data' from 'C:\\Users\\USERNAME\\Anaconda3\\envs\\py36\\lib\\site-packages\\cv2\\data\\__init__.py'>
>>> cv2.data.haarcascades
'C:\\Users\\USERNAME\\Anaconda3\\envs\\py36\\lib\\site-packages\\cv2\\data\\'
>>> cv2.__version__
'4.0.0'

不过很遗憾,3.2.x和3.4.x版本中没有这个模块...

所以你可以这样做:

if hasattr(cv2, 'data'):
    print('Cascades are here:', cv2.data.haarcascades)
else:
    print('This may not work:')
    print(normpath(realpath(cv2.__file__) + '../../../../../share/OpenCV/haarcascades'))
7

你可以用 cv2.__file__ 来获取这个模块的路径,然后用 os.path 来处理符号链接和进行一些路径操作。这行代码会返回我在 Mac OS 的 homebrew 安装中 haarcascades 文件的目录。其他安装方式也可能适用。

from os.path import realpath, normpath
normpath(realpath(cv2.__file__) + '../../../../../share/OpenCV/haarcascades')

撰写回答