python: OpenCV Root Directory

15,260

Solution 1

You can use cv2.__file__ to get path to the module and then use os.path to resolve symlinks and do some path manipulation. This line of code returns the directory of the haarcascades files on my Mac OS homebrew installation. It may work on other installations too.

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

Solution 2

It seems there is little hope of having a single mechanism which would be portable across time and space (versions and platforms/environments), but there is some progress - I don't know which version introduced it, but 4.0 has it:

cv2.data.haarcascades - string pointing to a directory, e.g.:

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

But unfortunately, for 3.2.x and 3.4.x there is no such module...

So you could do:

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'))
Share:
15,260
Matt W-D
Author by

Matt W-D

Updated on June 09, 2022

Comments

  • Matt W-D
    Matt W-D almost 2 years

    I am using OpenCV for various object detectors, and I am finding it difficult to write portable code.

    For instance, to load a face detector, on a mac with OpenCV installed via homebrew, I have to write:

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

    This is not portable; if I wish to change to another machine I'll have to determine another absolute path and change this code.

    Is there a variable that holds the OpenCV root for OpenCV? That way I could write something like:

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

    UPDATE: It looks like this is not just a problem for me; it is also a problem for the OpenCV documentation. The documentation contains the following broken example code:

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

    This would be simple to avoid if there was a way to infer where examples like lena.jpg and the pre-trained classifiers were installed.

    Source: http://opencv.willowgarage.com/documentation/python/objdetect_cascade_classification.html (Retrieved 3/5/13)

  • Matt W-D
    Matt W-D about 11 years
    I don't think this will work. For instance, on OS X, the install location of the OpenCV root is extremely heterogeneous - it can be in /usr/local/share (homebrew), /sw/share (fink), /opt/local/share (macports). On linux, it's usually in /usr/share, except for custom installations which might be in /usr/local/share. And if the user does not have root, then they might install it in their home directory. A sys.platform switch unfortunately doesn't really handle this nonsense :(
  • Matt W-D
    Matt W-D about 11 years
    While this is slightly better than my absolute path solution, it's still pretty ugly. I'm going to have to do this every time I want to use some other loadable classifier in opencv - and as revisions to opencv roll out I'll have to keep on copying to keep up to date.
  • Tomasz Gandor
    Tomasz Gandor almost 5 years
    Unfortunately, this is not really portable. In Anaconda on Windows OpenCV 3.2 and 3.4 install the data to: <ENV_ROOT>/Library/etc/haarcascades