5分で出来る!? FastAPIとOpenCVで顔検出APIを作成してHerokuで公開

# はじめに
こんにちは。本記事は[自サイト](https://flat-kids.net/)のものを書き写したものになりますが、広く使ってもらえそうな内容だと思ったので思い切ってQiitaに投稿してみました。

さて、コンピュータビジョンを勉強していて、この技術をどのように具体的に使えるようにするのが良いか模索しています。その中でAPIを作るという手法は色々な環境・言語で共通モジュール的に使えて良い案の１つと思います。勿論デメリットもありますが。
APIを簡単に作れるPythonフレームワークが無いか探していたところ、FastAPIというものを見つけたので、FastAPIを使って顔検出APIを作成し、それをせっかくなのでHerokuで公開まで一気に行きたいと思います。

さて、5分で出来るでしょうか（笑）タイマースタート！

# FastAPIとは
FastAPIは、標準のPython型ヒントをベースにPython 3.6+でAPIを構築するための、モダンで高速（ハイパフォーマンス）なWebフレームワークです。とても使いやすいフレームワークなので是非とも沢山の人に利用してほしいです。
公式サイトは[https://fastapi.tiangolo.com/](https://fastapi.tiangolo.com/)です。

# 顔検出APIとは？
顔検出したい画像をアップロードすると、JSONで検出できた数や矩形座標を返すAPIを作成します。その結果を利用して、よくある感じで枠を付けてみるとこんな感じになります。
![screenshot.181.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/ae332808-84c4-10d5-929f-bdd9e1b8483b.png)

画像：http://gahag.net/

# 前提
予め以下を実施して下さい。

- Herokuユーザ登録済み(Freeプラン)
- Githubユーザ登録済み


以下は実施した方がいいと思いますが、今回は必須ではありません。

- デバッグ用にPCにPythonインストール
- VSCodeなどのデバッグ環境インストール

# 手順

1. GitHubリモートリポジトリ作成
2. Herokuにデプロイ
3. API完成!?

# ①GitHubリモートリポジトリ作成
ソースコードの詳細は後程自サイトにて書いていきたいと思います。今回使用するソースコードは[Github](https://github.com/MamiTakata/fastapi-cv)にあります。自分のGithubリモートリポジトリを作成してソースを置いて下さい。

構成は以下のようになっています。
```
.
├── cascades
│   └── haarcascade_frontalface_default.xml
├── detect
│   └── detect_face.py
├── .gitignore
├── Aptfile
├── Procfile
├── const.py
├── main.py
├── requirements.txt
└── women.jpg
```

「cascades/haarcascade_frontalface_default.xml」は顔検出できるカスケード識別器の学習済みファイルです。「detect/detect_face.py」には顔検出するロジックが書いてあります。「.gitignore」はgit管理したくないものを書いてます。「Aptfile」はHerokuでOpenCVを使うのに必要なファイルです。詳細は後述しています。「Procfile」はHerokuでFastAPIを動かすのに必要なファイルです。「const.py」はCONSTを使うのに楽なので使用しています。「main.py」はuvicorn により実行されるファイルです。「requirements.txt」は依存ライブラリを管理するファイルです。HerukuでDeployするために必要です。「women.jpg」はサンプル用画像です。

# ②Herokuにデプロイ
さて、ソースの準備が出来たので、HerokuでAPI公開の準備をします。
まずはCreatNewAppをします。
![screenshot.173.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/d4c6f68c-d661-784c-eb2a-6409b2646efb.png)

アプリ名を付けます。
![screenshot.174_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/4ebacf4c-9e47-4fd4-7c92-0e011ccce4a5.png)

Deployタブを選択して、自身のGithubアカウントと接続した後、デプロイするリポジトリを選択します。
![screenshot.182_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/a7033570-4942-87db-b138-f426d2c35652.png)

OpenCVは「opencv-contrib-python」パッケージをインストールしていますが、これだけだとimportエラーが出てしまいます。「ImportError: libSM.so.6: cannot open shared object file: No such file or directory」そのため、「buildpacksの追加」と「Aptfileファイル作成」が必要になります。Aptfileはソース一式の中に用意してありますので、Herokuでbuildpacksの追加のみ実施します。SettingsタブのBuildpacksにて「[https://github.com/heroku/heroku-buildpack-apt](https://github.com/heroku/heroku-buildpack-apt)」を追加します。

![screenshot.179.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/175ad4cf-b7d5-8feb-5f13-09de8b0efc8e.png)

Deployタブに戻って、Deployします。今回はManualDeployを選択します。
![screenshot.177.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/f34cee29-cf71-3bad-efce-eddbd243f7c4.png)


# ③API完成!?
Deployが運よく成功しましたら、Herokuの画面右上にある「Open app」を押します。
{“detail”:”Not Found”}
ような表示が出ましたでしょうか。エラーじゃん！！という方ごめんなさい。

作成したAPIを呼び出すには、URLの後ろに/docsを付けると簡単です。
![screenshot.182.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/9455fb36-b2bb-39af-ae42-07a9a2d1ad0b.png)

「Try it Out」を押すと、実際に試せます。
![screenshot.183.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/a908bd15-0343-6f9e-8321-3d5581376bb9.png)

顔検出したい画像を選択して、Executeします。こんな感じで結果が返ってきましたでしょうか？
![screenshot.184.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280388/4c752020-0896-371c-a356-9e3ea5b86c5e.png)

**(注)画像サイズについて**
画像サイズは0.2Mb以下のものを使用しています。サイズが大きいときちんと検出できないです。色々調整が必要なようです。


# おわりに
これで終わりです。タイマーストップ！5分以内でしたか？（笑）
上手くいかなかった方、本当にごめんなさい:sweat_smile:謝るだけで解決せずにごめんなさい:sweat_smile::sweat_smile:
FastAPIをHerokuでDeployする方法が分からなかったので、記事を作成してみました。誰かのお役に立てたら幸いです:blush: