M1 MacにOpenCV4(C++/Python3)をインストールする方法

# 動作環境
* M1 MacBookAir(2020)
* conda(Miniforge)
* OpenCV4.5(with_contrib)

#1. condaのインストール
```
conda create --name <env_name>
conda activate <env_name>
conda install -y python==3.8.6
```
#2. Numpyのインストール
```
% 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 ~
```
#3. OpenCVをソースからコンパイル
```
% 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
```

```
% 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=/Users/<user_name>/Downloads/opencv_contrib-4.5.0/modules \
  -D PYTHON3_EXECUTABLE=/Users/<user_name>/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 \
  -D OPENCV_GENERATE_PKGCONFIG=ON \
  -D WITH_FFMPEG=ON ..
% make -j8
% sudo make install
```
参考にした[1]では，恐らくPython版で使うことが想定されているようだが，私はC++ と VideoCapture も使いたかったため，末尾に`-D OPENCV_GENERATE_PKGCONFIG=ON \-D WITH_FFMPEG=ON`を追記している．

そのため，C++でコンパイルするため，`/usr/local/lib/pkgconfig/opencv4.pc`へのパスを通す．

```~/.zshrc
export PKG_CONFIG_PATH==/usr/local/lib/pkgconfig
source ~/.zshrc
```

#4. 動作確認
```
% conda activate <envi_name>
% python
>>> import cv2
>>> cv2.__version__
```
Pythonに関しては，4.5.0と表示されればOK.

次にC++．
Object Detection系でC++で動く良いサンプルがないかGitHubを物色したところ，YOLOを手軽に動かせるリポジトリ[2]を発見（Detection以外のタスクもほぼ網羅されている）．
`ObjectDetection-YOLO`をclone後以下を実行し，pretraind modelをダウンロード & コンパイル．

```
% sh getModels.sh
% g++ -std=c++11 object_detection_yolo.cpp `pkg-config --cflags --libs opencv4` -o object_detection_yolo
% ./object_detection_yolo --image=bike.jpg
```

![bike_yolo_out_cpp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227432/760762e1-c010-3ff4-1312-ca5ebd838785.jpeg)
任意の画像で実行して物体検出されればOK．

# 1つ問題が．．．
webcam入力でc++からDetectionして，AppleSiliconはえええというのをやりたかったのだが，opencvをcmake時にffmpegが認識されておらず，VideoCaptureが使えないという問題が発覚．この理由は，恐らくだが，私の環境には，x86_64環境とarm64環境の2つ同居してる関係で`/usr/local/bin/ffmpeg`（x86_64コンパイル(clang-11.0.0)）と`/opt/local/bin/ffmpeg`（arm64コンパイル(clang-12.0.0)）があり，前者が参照されているのが原因と思われる．識者がいれば，解決方法をコメントで教えていただけると幸いである．

（2021.02.16 追記）
原因は，予想通り`/usr/local/bin/ffmpeg`がx86_64コンパイル(clang-11.0.0)であるためだった，多少強引だが，`/usr/local/bin/`にarm64コンパイル(clang-12.0.0)のffmpegのバイナリを突っ込んだら，コンパイル時に認識されるようになった．
また，色々カメラアプリを入れていたせいで，cap(0)がSnapCameraになっていたのも原因だった．

```console
% ffmpeg -list_devices true -f avfoundation -i dummy
ffmpeg version N-100400-g001bc594d8 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.27)
  configuration: --prefix=/opt/local
  libavutil      56. 62.100 / 56. 62.100
  libavcodec     58.115.102 / 58.115.102
  libavformat    58. 65.100 / 58. 65.100
  libavdevice    58. 11.103 / 58. 11.103
  libavfilter     7. 93.100 /  7. 93.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
Changed waitThread to realtime priority!
Asked for all format descriptions...
[AVFoundation indev @ 0x11d70c7f0] AVFoundation video devices:
[AVFoundation indev @ 0x11d70c7f0] [0] Snap Camera
[AVFoundation indev @ 0x11d70c7f0] [1] FaceTime HD Camera
[AVFoundation indev @ 0x11d70c7f0] [2] EpocCam
[AVFoundation indev @ 0x11d70c7f0] [3] Capture screen 0
[AVFoundation indev @ 0x11d70c7f0] [4] Capture screen 1
```


# 参考
[1] [Building and Installing OpenCV 4.5.0 on an M1 Mac](https://sayak.dev/install-opencv-m1/)
[2] [learnopencv/ObjectDetection-YOLO/](https://github.com/spmallick/learnopencv/tree/master/ObjectDetection-YOLO)
[3] [OpenCVを使ったC++コードをコンパイルする（CMake, GCC, pkg-config）](https://qiita.com/kekenonono/items/0fcf042bca2d3d17867a)
[4] [OpenCVのC++コードをMacでmakeする際のMakefile](https://qiita.com/wkentaro/items/3a770726deb8fa1f214a)