This post shows how to build and install OpenCV 4.5.0 on a MacBook Pro that comes with an M1 chip. Yes, you guessed it right - as of January 01, 2021, there’s no pre-compiled OpenCV binary compatible with this MacBook Pro variant. So, open up a terminal and get started!

Here's a brief summary of the configuration of my MacBook -

Note: The following steps should run well on an M1 MacBook Air too.

## Install Xcode and Homebrew

We start by executing sudo xcodebuild -license from a terminal.

When you execute the above command, you would need to accept the Xcode license. Then, in order to make use of Apple command line tools, we need to install it - sudo xcode-select --install.

Homebrew manages packages on a Mac. In order to install it execute the following - /usr/bin/ruby -e "%(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)".

You would want to add the command brew after the installation is complete. To do so, execute the following - nano ~/.zshrc

Then insert export PATH=\$PATH:/opt/homebrew/bin into it and press Ctrl + X from your keyboard. Then execute source ~/.zshrc from the terminal.

Note that the exact path to Homebrew might be different for your system, so please double check that.

Next up, we install a few system-level utilities required by OpenCV on a Mac.

## Install conda

My favorite Python virtual environment manager is virtualenv. Unfortunately, it does not play out that well with the new M1 chip. This is mostly because the pip-installable packages often break during their installations on the chip. This is why conda, specifically its miniforge distribution is the recommended package manager for a Mac shipped with M1. You can install it from here. This installs Python 3.8.

After the installation is complete, please create a new Python virtual environment by executing conda create --name <environment_name>. Then activate it by running conda activate <environment_name>.

Running conda install -y python==3.8.6 will install a few common Python packages for you. I highly recommend running this.

## Install NumPy

NumPy is needed by OpenCV. So, we need to install it before we build and install OpenCV. Apple provides a numpy wheel that is compatible with the M1 chip. Follow the steps below to install it -

% wget https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha0/tensorflow_macos-0.1alpha0.tar.gz
% tar xvf tensorflow_macos-0.1alpha0.tar.gz
% cd tensorflow_macos/arm64
% pip install --upgrade --no-dependencies --force numpy-1.18.5-cp38-cp38-macosx_11_0_arm64.whl
% cd ~


Note: Be sure to activate your conda environment before doing the pip-install.

## Compile OpenCV

First, let's download the OpenCV and OpenCV extended module files and prepare them for compilation.

% wget -O opencv.zip https://github.com/opencv/opencv/archive/4.5.0.zip
% wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.5.0.zip
% unzip opencv.zip
% unzip opencv_contrib.zip
% cd opencv-4.5.0
% mkdir build && cd build


Now, we are all set to fire the cmake command that would build OpenCV for us. Let’s review it briefly -

% cmake \
-DCMAKE_SYSTEM_PROCESSOR=arm64 \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DWITH_OPENJPEG=OFF \
-DWITH_IPP=OFF \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D PYTHON3_EXECUTABLE=/Users/sayakpaul/miniforge3/envs/dev/bin/python3 \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D OPENCV_ENABLE_NONFREE=ON \
-D BUILD_EXAMPLES=ON ..


As per this issue comment, DCMAKE_SYSTEM_PROCESSOR, DCMAKE_OSX_ARCHITECTURES, DWITH_OPENJPEG, and DWITH_IPP are needed to be set during the compilation step. Also, please pay attention to the following arguments - OPENCV_EXTRA_MODULES_PATH and PYTHON3_EXECUTABLE. For these two arguments, you would want to first determine the paths and then supply them accordingly.

Now, before you run the above cmake command, activate the conda environment you created in an earlier step (conda activate <environment_name>) if you haven’t already. The compilation took ~3 minutes for me and it should produce outputs like so -

Next, we launch the make command - make -j8. With all the eight cores (j8 stands for eight cores here) chugging along, this step took ~8 minutes for me. You can adjust the j option with respect to the hardware available. After it’s done you should get an output like so -

The final step here is to execute - sudo make install. It should take just a few seconds to complete execution. Upon successful completion, you should get an output like so -

To do this, we first need to locate the .so file generated during the compilation step. We can do this with the mdfind command -

% mdfind cv2.cpython
/.../opencv-4.5.0/build/lib/python3/cv2.cpython-38-darwin.so
/usr/local/lib/python3.8/site-packages/cv2/python-3.8/cv2.cpython-38-darwin.so
...


Please note that I obfuscated some parts of the outputs for privacy reasons. In the above output, we can see the absolute locations for the .so files that were generated. Now, we need to execute the following to sym-link one of the .so files in our current Python virtual environment -

% cd /.../miniforge3/envs/dev/lib/python3.8/site-packages
% ln -s /usr/local/lib/python3.8/site-packages/cv2/python-3.8/cv2.cpython-38-darwin.so cv2.so


Please double-check the paths before executing the commands.

And that’s it!

You can test the installation by executing the following -

% conda activate <environment_name> (if you haven't already)
% python
>>> import cv2
>>> cv2.__version__


It should print '4.5.0'.