LKY 只有原創內容的 Blog

今之能者,謂能轉貼,至於魯蛇,皆能轉貼。不原創,何以別乎?

如何在 Apple Silicon 上安裝 OpenCV 4.5.3 與 TensorFlow 2.5 給 Python 用?

Lin, Kao-Yuan's Avatar 2021-07-26

  1. 1. 坑有哪些?
  2. 2. Step 0: 安裝 Xcode 與 brew
  3. 3. Step 1: 安裝 Conda
  4. 4. Step 2: 安裝 Numpy(in tensorflow-deps)
    1. 4.1. 小心有坑!
    2. 4.2. 我已出坑
  5. 5. Step 3: 編譯 OpenCV
    1. 5.1. 小心有坑!
    2. 5.2. 我已出坑
  6. 6. Step 4: 連結 OpenCV
  7. 7. Step 5: 安裝 TensorFlow
  8. 8. 參考資料

我來證明 Apple Silicon 現在也可以煉丹了!

下圖是筆者在 Apple Silicon 上跑起了 OpenCV 4.5.3 與 TensorFlow 2.5.0。

在朋友推坑之下,筆者入手了 Apple Silicon (以下簡稱M1) MacBook。

這兩天做完相容性驗證之後,準備把舊的 Intel MacBook 賣掉。

(好尷尬啊,台灣人沒有中國大陸身份證,不知道 Apple 會怎麼處理?)


相容性驗證有哪些項目?主要驗證我常用的 OpenCV、scikit、numpy、TensorFlow 等套件如何安裝?能不能正常跑?

經過大量苦逼無聊的工作後,發現目前還是不能常規無痛安裝,必須以 workaround 的手段安裝。

坑有哪些?

  • 目前網上充斥各種過時、有錯誤的野生安裝方法。
  • 就算最多人參考的國外大神帖子,也有過時或出錯的地方,造成安裝完全失敗。

經過我徹夜摸索後,修正國外大神帖子中部分問題,終於跑通一套可以正確安裝 OpenCV 當下最新版(4.5.3)與 TensorFlow 2.5.0(僅限 Apple 分支) 的流程。

以從頭乾淨安裝來說,目前各種 Python 的數據科學 package 幾乎只能走 conda 安裝,疑似還是要依賴 Rostta2?這部分我就不懂,有請熟悉編譯器或虛擬機器的大神補充。

Step 0: 安裝 Xcode 與 brew

這步驟我覺得對 macOS 上的開發者來說是必備且熟練了,所以懶得寫。

記得 brew 要安裝 Apple Silicon 用的版本。

1
2
$ which brew
/opt/homebrew/bin/brew

Apple Silicon 用的 brew 版本,路徑是 opt 開頭的。

Step 1: 安裝 Conda

這個連結,下載並執行:

https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh

這裡就會包含有針對 Apple Silicon 最佳化的 Python 3.9,也一併安裝。


我沒有要做環境隔離,所以直接 conda activate 進入到名為 base 的 conda env。

你嘗試下圖的指令,看是不是跟我一樣?

這代表成功切換虛擬環境,並用上 Python 3.9

Step 2: 安裝 Numpy(in tensorflow-deps)

小心有坑!

按照國外大神提供的步驟,在這一步就出錯,走不下去,原因是內容有些過時了。

你照做就會看到以下的錯誤:

1
2
3
$ (base) ➜ pip install --upgrade --no-dependencies --force numpy-1.18.5-cp38-cp38-macosx_11_0_arm64.whl

ERROR: numpy-1.18.5-cp38-cp38-macosx_11_0_arm64.whl is not a supported wheel on this platform.

原因:這個 numpy 包的「cp38」代表是給 Python 3.8,版本號多或少一點都不行!可是最多也只出到 3.8,但指定的 conda 環境已經變成 Python 3.9,而且為了 M1 優化也是從 Python 3.9 開始,所以這邊就衝突了。那這個坑怎麼辦呢?

我已出坑

不論只安裝 OpenCV 與 TensorFlow 其中哪一個,這一步都是必要的前置步驟。

這邊直接安裝 Apple 官方提供的 tensorflow-deps,會聯同 numpy 一起搞定。上面單獨安裝一個 .whl 的步驟就不用了。

conda install -c apple tensorflow-deps

安裝完以後測試看看,有 numpy 版本號出現就是可以了。

python -c "import numpy as np;print(np.__version__)"

Step 3: 編譯 OpenCV

通常說到編譯,就會想到等很久。還好我們用的是 Apple Silicon,所以這次很快,我記得開始編譯之後就去洗澡,洗完出來剛好完成。

在家目錄下載 OpenCV 與他的延伸套件、解壓縮、進入編譯資料夾。

1
2
3
4
5
6
7
8
mkdir /Library/OpenCV && cd /Library/OpenCV
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.5.3.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.5.3.zip
unzip opencv.zip
unzip opencv_contrib.zip
mv opencv.zip opencv_contrib.zip ~/Downloads
cd opencv-4.5.3
mkdir build && cd build

然後 cmake

小心有坑!

外國大神提供的指令這邊有錯,照做會得到這個錯誤。

1
2
Make Error: The source directory "/Library/OpenCV/opencv-4.5.3/_" does not exist.
Specify --help for usage, or press the help button on the CMake GUI.

我已出坑

我撞牆多次後,已經為大家修正。

首先在 conda 環境下輸入 which python,得到以下結果:

1
2
(base) ➜  ~ which python
/Users/lky/miniforge3/bin/python

然後把輸出的路徑放到以下 cmake 指令中,PYTHON3_EXECUTABLE 後面那串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 OPENCV_EXTRA_MODULES_PATH=/Library/OpenCV/opencv_contrib-4.5.3/modules \
-D PYTHON3_EXECUTABLE=<替換成 which python 給你的輸出> \
-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 ../

接著輸入 make -j8,這就是編譯的步驟。

j8 就是用八個核心,目前能買到的 Apple Silicon 都是八個核心,所以也沒有改多的空間了。

給大家看看我編譯的過程:

編譯完成後,執行 sudo make install,這一步就算完成了。

Step 4: 連結 OpenCV

將 macOS 上的 OpenCV 4 符號鏈接到虛擬環境 site-packages

輸入 mdfind cv2.cpython 應該能看到這兩行以「.so」結尾的路徑,其他的路徑不管他

1
2
3
4
(base) ➜  ~ mdfind cv2.cpython
/Library/OpenCV/opencv-4.5.3/build/lib/python3/cv2.cpython-39-darwin.so
/usr/local/lib/python3.9/site-packages/cv2/python-3.9/cv2.cpython-39-darwin.so
...(其他的路徑不管他)...

我們要在虛擬環境的 site-packages 中產生一個假的「cv2.so」,實際上是連結到剛才編譯出來的那個「cv2.cpython-39-darwin.so」

1
2
cd /Users/<你的使用者名稱>/miniforge3/lib/python3.9/site-packages
ln -s /Library/OpenCV/opencv-4.5.3/build/lib/python3/cv2.cpython-39-darwin.so cv2.so

這一步做完,OpenCV 應該就安裝到 Python 能用了。來測試一下:

1
2
conda activate
python -c "import cv2 as cv;print(cv.__version__)"

結果應該要出現「4.5.3」。

Step 5: 安裝 TensorFlow

1
2
conda activate
python -m pip install tensorflow-macos

這一步做完,TensorFlow 應該就安裝到 Python 能用了。來測試一下:

1
2
conda activate
python -c "import tensorflow as tf;print(tf.__version__);print(tf.reduce_sum(tf.random.normal([1000, 1000])))"

結果應該要出現「2.5.0」還有以下隨機內容的 Tensor:

1
tf.Tensor(-48.841095, shape=(), dtype=float32)

到這裡,以下這些套件就安裝完成:

  • 針對 Apple Silicon 最佳化的 Python 3.9
  • OpenCV 4.5.3
  • TensorFlow 2.5.0

另外這些常用的 package 都這樣安裝:

1
2
3
4
conda install matplotlib
conda install scikit-image
conda install scikit-learn
conda install pandas

以後使用之前,都必須要先 conda activate 進入虛擬環境,這是目前還有一點不完美的地方。

參考資料

本文最后更新于 天前,文中所描述的信息可能已发生改变