M1 mac でmediapipeを使う

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) それはさておきpythonの仮想環境がよくわからぬ

# mediapipeがM1 macに公式対応していない
2022年4月の段階ではまだ対応していないようですが、
使えるようにしてくれている方がいましたのでありがたく使わせていただきます。

# 準備
私はminiforgeでpythonの仮想環境を準備しました。
python3.8をベースとした万能環境の構築には、以下の記事が大変参考になります。

https://qiita.com/c60evaporator/items/aef6cc1581d2c4676504#%E5%90%84%E7%A8%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

※protobufが必要な場合がありますので、インストールしてください。（brew install protobuf）
※Bazelが必要な場合がありますので、インストールしてください。
※モジュールをインストールした場合は、ターミナルを再起動するとよさそうです。

# mediapipe-siliconのビルド
以下のgithubを利用させていただきます。
こういうgithubの正しい使い方がいまいちわかっていないのですが、何とか動かせたので手順をメモしておきます。

https://github.com/cansik/mediapipe-silicon

### conda 環境に入る

```
conda activate ＜自分で作った環境名＞
```
としてcondaの万能仮想環境をアクティベートします。

### git cloneする

まずgithubページ右上にあるcodeボタンからURLをコピーします。
次にターミナルで適当なディレクトリに移動し、
```
git clone https://github.com/cansik/mediapipe-silicon.git
```

とします。

### ビルドする

DLが終わったら
```
cd mediapipe-silicon
```
でディレクトリの中に移動し、
```
./build-macos.sh
```
でビルドを実行します。ビルドは少し時間がかかります。

ビルドが完了するとdistディレクトリの中に「mediapipe_silicon-0.8.9-cp38-cp38-macosx_11_0_arm64.whl」という感じのファイルができています。

### インストールする

```
cd dist
pip install mediapipe_silicon-0.8.10.1-cp38-cp38-macosx_11_0_arm64.whl
```
としてsilicon版のmediapipeをインストールします。
（pip install に続くmediapipeのバージョンはビルドされた最新のものにファイル名を合わせてください。）
インストールがpipでいいのかという気もしますが、condaではインストールできませんでした。

```
python
>>import mediapipe as mp
```
これでエラーが出なければインストールはOKのはずです。pipを使っているのでパスも通っているはずです。

実際のスクリプトも動いてくれることを祈ります！

# サンプルスクリプト
公式のデモをすこし改造したサンプルスクリプトです。
黒い画面にWEBCAMで捉えた顔のメッシュを表示します。

```python:mediapipe_black.py
import cv2
import numpy as np
import mediapipe as mp

v_cap = cv2.VideoCapture(1)#カメラのIDを選ぶ。映らない場合は番号を変える。

with mp.solutions.face_mesh.FaceMesh(#mesh化の設定をしてその処理名をface_meshとする
    max_num_faces=1,refine_landmarks=True,min_detection_confidence=0.5,min_tracking_confidence=0.5) as face_mesh:
    #↑顔の数, ランドマークのリファイン?, ランドマーク検出成功判定の閾値, ランドマークトラッキング成功判定の閾値
  while v_cap.isOpened():
    success, image = v_cap.read()#キャプチャが成功していたら画像データとしてimageに取り込む
    results = face_mesh.process(image)#メッシュ化計算の結果がresutsに入る
    # 表示画面の背景を黒で塗りつぶす
    image_blank = np.zeros((int(v_cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), int(v_cap.get(cv2.CAP_PROP_FRAME_WIDTH)), 3))
    image = image_blank

    if results.multi_face_landmarks:
      for face_landmarks in results.multi_face_landmarks:
        mp.solutions.drawing_utils.draw_landmarks(
            image=image, landmark_list=face_landmarks, connections=mp.solutions.face_mesh.FACEMESH_TESSELATION,
            #↑画像データ, ランドマークのリスト, メッシュの繋ぎ方?(テッセレーション)
            landmark_drawing_spec=None,connection_drawing_spec=mp.solutions.drawing_styles.get_default_face_mesh_tesselation_style())
            #↑わからぬ, わからぬ
    cv2.imshow('MediaPipe Face Mesh', cv2.flip(image, 1))#imageを鏡像で表示
    if cv2.waitKey(5) & 0xFF == 27:#ESCキーが押されたら終わる
      break

v_cap.release()

```

**※画面が映らない場合は4行目のカメラIDの変更**を試してみてください。

# 実行結果

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/ae37b940-13d2-80d2-b672-7ad12a102d60.png" width =400>

スマホに映した画像をカメラに認識させてみました。
さてこれは誰でしょう。なんとなく面影があるような。元の顔を想像できるでしょうか？

<details><summary>こたえ</summary><div>

正解は芦田愛菜さんでした。
当たった方、すごい！
</div></details>

# 前の記事
https://qiita.com/Ninagawa_Izumi/items/4449c4de7d5b8baa37ed