VS CodeでOpenCVする時に、MacBook内蔵Facetimeカメラが使えない（セキュリティーとプライバシー）

# とりあえず、最短距離でOpenCVを試してみたい

Mac/iMacで、OpenCVやってみたい、さぁ、とりあえずサンプルを、と思ったとき、以下のような最短手順で、内蔵Facetimeカメラを使った顔認識を試すことができます。



## ダウンロード／インストール

```
pip3 install -U opencv-contrib-python
curl -OL https://github.com/opencv/opencv/archive/4.5.1.zip
unzip 4.5.1.zip
```


## 実行

```
cd opencv-4.5.1/samples/python

python3 facedetect.py
カメラへのアクセスが必要と言われたら、[OK]を押して、もう一度実行。
自分の顔で試したり、そのへんに転がっていた集合写真などをかざせば、オッケー。
（escキーで終了）
```


（蛇足）ダウンロードは、curlでもwgetでもお好きな方で。

```
wgetが好きな人は、curlの代わりに、
wget https://github.com/opencv/opencv/archive/4.5.1.zip
brewでwgetをインストールする場合は、
brew install wget
```



# VS Codeでやってみると、あれ？？？

VS Code便利！、ターミナルもVS Codeで、となっている人も多いと思います。
で、やってみると、んんー、と考えた後、エラーが出ます。

```
Abort trap: 6
```

なにこのエラーメッセージ。そっけない。ググッてみたら、C++コード実行時例外発生、ということで、いろいろな局面で出る模様。

Facetime HD Camera関係でググると、カメラのアクセスがシステムによって許可されていないから、ということ。「システム環境設定／セキュリティーとプライバシー／カメラ」で、登録するやつですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/e06b981b-e55e-6942-7f29-9729c7c37a0b.png" width="320">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/6eb2f9eb-5dee-69aa-8ca6-9c67dd0f5287.png" width="320"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/da5ba55d-2f02-c8cc-597d-d0354afbac3a.png" width="320">

ターミナルアプリは、許可されているのでオッケー。はい、ここにVS Codeも登録したら良いです。とはならない。。

例えば、ブラウザ経由で動いているJupyterがカメラ／マイクを使おうとするとき、Jupyterからリクエストがでて、ここに登録する流れができますが、VS Codeはそれがないことが問題。マイクへのアクセスも同様。


## とりあえずの解決策

ターミナルから、`code .`とコマンドを打ってVS Codeを起動すればよい。カメラ／マイクへのアクセスは、起動した親のアクセス権が適応される、ということ。

codeコマンドを有効にするには、
1. VS Codeのコマンドパレットから、shellと入力。
2. 「シェル コマンド: PATH内に'code'コマンドをインストールします」をクリック。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/67db433b-552c-81b3-e180-8df844321414.png" width="480">

## 根本的な解決

VS CodeのGitHub.comリポジトリで、issueが上がっています。

'VSCode terminal doesn't allow/request permissions to access media devices #95062'
https://github.com/microsoft/vscode/issues/95062

問題は認識されているが、未解決。
根本的な解決は、VS Codeが「セキュリティーとプライバシー」に登録される流れを実装すること。しばし待て、ですね。

## 危険なゴニョゴニョ

おとなしく、待つ方が賢明です。それでもやりたい人は、データベースを直接書き換えます。アップデートなどでデータベースの構造が変化していたりすると、バグります。

リカバリーモードでシステム再起動（cmd+R長押し）して、System Integrity Protection（SIP、システム整合性保護）を一時的に無効化しないとダメ、というサイトが多数見られますが、不要です。

代わりに、ターミナルにフルディスクアクセスの権限を与えます。

![スクリーンショット 2021-02-20 13.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/0f24fb32-5dfa-6f8c-6c91-ddf409dcea5a.png)

Mojaveは、これで行けました。

```
# TCC.dbを念の為バックアップして、データベースを編集
cd ~/Library/Application\ Support/com.apple.TCC/
cp TCC.db TCC.db.bak
sqlite3 TCC.db  # sqlite>プロンプトが出ます。

# Mojaveの場合：
#  VS Codeにカメラへのアクセス権を追加
INSERT into access VALUES('kTCCServiceCamera',"com.microsoft.VSCode",0,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);

#  マイクへのアクセス権を追加
INSERT into access VALUES('kTCCServiceMicrophone','com.microsoft.VSCode',0,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);
```


![スクリーンショット 2021-02-20 13.15.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/01158bd0-79d3-fd1a-01e1-8c4f2dae18ff.png)


BigSurの場合（すみません、未検証です。どなたか、冒険心と興味あれば追試を。危険です。）

```
# BigSurの場合：

GitHub.comのissueでBigSurを検証してくれた人がいました。カラムが12から13に増えたようで、1を一つ増やしてオッケーだったようです。

INSERT into access VALUES('kTCCServiceCamera',"com.microsoft.VSCode",0,1,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);

INSERT into access VALUES('kTCCServiceMicrophone','com.microsoft.VSCode',0,1,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);
```


# おまけ。OpenCVのサンプル実行

色々試すには、メニューアプリdemo.pyを使う。

```
cd opencv-4.5.1/samples/python
python3 samples/python/demo.py
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/e4275bba-6430-377e-826e-c813ac1e118c.png" width="240">

読みにくかったので、フォントやフォントサイズを改変しました。各エントリーが、かなりいい加減に作られていて、ボロが出ます。もうちょっとメンテしても良さそうな。。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/8e9bd576-d3a1-7226-a9c6-d3a70d822a3b.png" width="420">

ビデオソースを使うデモとしてわかりやすいのは、こんなところで。

    facedetect.py
    mosse.py
    edge.py

基本的に`esc`キーで終了、となっているものが多いかな？

レナさんファンは、チュートリアルにある、こちらなど、どうぞ。

```
cd opencv-4.5.1/samples/python
python3 tutorial_code/ImgTrans/Filter2D/filter2D.py
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/28b7ce9e-8bc1-f4f9-3952-538527f9e731.png" width="320">