OpenCV, Python 3, and Homebrew Walkthrough

Post by Gravity Jack research team member, Marc Rollins.

Introduction

Do you want to use OpenCV, but can’t get it to work with Python 3? You’ve come to the right place! Here at Gravity Jack we tackle computer vision problems using OpenCV as one of the tools in our arsenal. It’s very useful for implementing computer vision algorithms, but getting the library installed properly isn’t always easy. Since our research team all develops on OS X, we also make use of the Homebrew package manager. Usually Homebrew makes dependency management a breeze, but OpenCV is a curious exception to this rule. This seems especially true when trying to use the Python bindings that OpenCV provides. Even though OpenCV includes the Python 2 bindings by default, the same is not true of Python 3. What follows are the instructions to correctly install.

Installation

I’ll assume that Homebrew is up-to-date and brew doctor doesn’t bring up anything serious before installing OpenCV. There are two steps to correctly install Python support. First install the opencv3 package with Homebrew, and then tell Python 3 where to look for the OpenCV binary:

$ brew install opencv3 --with-python3 --c++11 --with-contrib
$ brew link --force opencv3

Then fire up Python and import the OpenCV module. Despite OpenCV 3 being installed, the Python package is still named cv2. Everything should go off without a hitch:

$ python3
Python 3.5.1 (default, May 20 2016, 12:52:19)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
3.1.0
>>> # It worked!
Additional step for virtualenv users

So far I’ve assumed you’re working with the standard Python installation. If you’re using a virtual environment, there is one more step to get Python to recognize the OpenCV package. Open a command prompt and cd to the directory where your virtualenv is installed. Here I assume that the virtual environment exists in the venv directory. Then run this command:

echo /usr/local/opt/opencv3/lib/python3.5/site-packages >> venv/lib/python3.5/site-packages/opencv3.pth

And you should now be able to import cv2 from within your virtual environment! If you have a different Python version than 3.5, you will need to change the major version numbers in the command above. (i.e. If you are using Python 3.4.3, replace python3.5 above with python3.4)

If something went wrong, check out the Troubleshooting section below.

Explanation

Let’s break down the commands and options a little bit:

brew install opencv3 — This specifies the package to install. Note that Homebrew has both an opencv and opencv3 package. The opencv formula will install the latest version of OpenCV 2.

--with-python3 — Tells Homebrew to include Python 3 support for OpenCV.

--c++11 — Tells Homebrew to build with C++11 support. By now you’re hopefully using a compiler that supports modern C++!

--with-contrib — This is optional, but recommended. The contrib module of OpenCV contains some experimental features, including a number of useful feature descriptors like SIFT, SURF, and FREAK.

Troubleshooting
Import error

After opening Python and importing OpenCV, you may run into an ImportError: No module named 'cv2'. This error can occur for one of three reasons:

  1. You forgot to install using the --with-python3 option. Don’t worry, it happens to the best of us! Simply brew reinstall opencv3 --with-python3 --c++11 --with-contrib to reinstall with Python 3 support. If that doesn’t work, go to the next step.
  2. OpenCV was not linked correctly. Run the command brew unlink opencv3 && brew link --force opencv3. That should successfully re-link the python libraries.
  3. You’re inside a virtualenv. If you’re using a virtual environment, you may have forgotten the final installation step. Follow the instruction above.
Undefined symbols error

During installation with brew, you may come across an undefined symbols error that looks like this:

Undefined symbols for architecture x86_64:
  "Imf_2_2::Chromaticities::Chromaticities(Imath_2_1::Vec2<float> const&, Imath_2_1::Vec2<float> const&, Imath_2_1::Vec2<float> const&, Imath_2_1::Vec2<float> const&)", referenced from:
      cv::ExrDecoder::ExrDecoder() in grfmt_exr.cpp.o
  "Imf_2_2::Header::Header(int, int, float, Imath_2_1::Vec2<float> const&, float, Imf_2_2::LineOrder, Imf_2_2::Compression)", referenced from:
      cv::ExrEncoder::write(cv::Mat const&, std::__1::vector<int, std::__1::allocator<int> > const&) in grfmt_exr.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libopencv_imgcodecs.3.1.0.dylib] Error 1
make[1]: *** [modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/all] Error 2
make: *** [all] Error 2

If you happen to see this, the workaround is simple: add the --without-openexr option to your installation command:

install opencv3 --without-openexr --with-python3 --c++11 --with-contrib

This error has something to do with the Imf_2_2 class, which is part of OpenEXR. Unless you specifically need OpenEXR, you can safely install OpenCV without it.

RELATED ARTICLES