#6 PowerApps アプリ で撮影した画像を FaceAPI で感情分析してみました


## 概要
PowerApps のカメラで撮影した画像を API Management 経由で FaceAPI に転送し、その画像の分析結果「感情、性別、年齢」を PoweApps に表示するアプリの実装手順を数回に分け記載しています。また、並行して、その分析結果を CosmosDB に保存しておき、PowerApps からの累積情報取得リクエストにより累積クエリ結果「感情分布、性別分布」を PowerApps に返し、円グラフ表示する機能の実装手順も複数回に分け記載します。なお、PowerApp の画面作成については省略し、APIコール部分とその戻り値の部分に焦点をあてて記載しています。
本アプリの全体構成は下図となります。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/8667aa79-9fb3-7df1-c1d6-cc170bf759df.png)

今回（第６回目）の構成箇所は下図の部分となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/d3c9a672-2bbe-a3de-4c90-88071bfbce2d.png)

第６回目は、[第５回](https://qiita.com/turupon/items/f3a739988a35f1647d65) で作成した Flow を PowerAppsアプリケーション からコールし、分析結果が得られることを確認してみます。第１回〜第５回 で作成したAzure側の処理が行われた結果の PowerAppsアプリケーションの動きは以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/1dfb3f1a-94e4-1dee-6e57-fafe1d3cfd63.png)

---

## 実行環境
macOS Big Sur 11.3
Python 3.8.3

---

### PowerAppsアプリケーション構成
画面構成とそれぞれのオブジェクトは以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/a5bd3bc9-52ed-1e4d-5a46-955482381387.png)

撮影した画像と分析情報は、コレクション「Photos」に保存されます。

|項目名|内容|分析前の値|分析後の値|表示オブジェクト|
|-|-|-|-|-|
|No|シーケンシャル番号|番号|番号|非表示|
|Emotion|感情情報| Not yet | 怒, 侮, 嫌, 恐, 幸, 無, 悲, 驚 のいずれか|Gallery1.Title1.Text|
|Data|分析情報|Base64テキストデータ|感情確率、性別、年齢|Gallery1.Subtitle1.Text|
|Image|撮影した画像|カメラ画像|カメラ画像|Gallery1.Image2.Image|

---

## PowerAppsアプリケーションの仕様
PowerAppsアプリケーションの簡単な仕様は以下となります。
カメラ「Camera1」で撮影された画像は、ギャラリー「Gallery1」に紐付けされた コレクション「Photos」に保存されます。スキャンアイコン「NextArrow1」を押すと、前回作成したFlowがコールされ、その分析結果をコレクション「Photos」に反映します。

カメラ「Camera1」の「OnSelect」には以下の設定をおこないます。

```
UpdateContext({result: "Not yet"});
UpdateContext({idnum: idnum + 1});
UpdateContext( { photouri: JSON(Camera1.Photo,JSONFormat.IncludeBinaryData) } ); 
Collect( Photos, { No: idnum, Emotion: result, Data: Substitute( photouri, """",  "" ) , Image:Camera1.Photo} )
```

スキャンアイコン「NextArrow1」の「OnSelect」は以下の設定をおこないます。

```
UpdateContext({flow_res: iTuruFlowFace.Run(ThisItem.Data)});
Patch(Photos, First(Filter(Photos, No=ThisItem.No)), {Emotion: flow_res.emotion, Data: flow_res.data})
```

---

## Flowコール
前述の

```
UpdateContext({flow_res: iTuruFlowFace.Run(ThisItem.Data)});
```

において、「iTuruFlowFace.Run(ThisItem.Data)」により、コレクションの「Data（Base64テキストデータ）」を引数として Flow がコールされます。　Flow の戻り値は「flow_res」に返されます。

```
Patch(Photos, First(Filter(Photos, No=ThisItem.No)), {Emotion: flow_res.emotion, Data: flow_res.data})
```

戻り値の「flow_res」はJSON形式ですので、コレクション「Photos」の「Emotion」へは「flow_res.emotion」、「Data」へは「flow_res.data」として、それぞれの項目にその結果を反映させます。

---

## PowerAppsアプリケーションのテスト
カメラで撮影した画像データの分析結果は以下となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544022/e471f09f-d4e2-40e6-3060-439a92fc51a3.png)


問題なく分析結果を取得できました。これで PowerAppsアプリケーション から Flow -> PowerAppsカスタムコネクタ -> APIM -> Functions -> FaceAPI にて、想定する戻り値を画面表示できていることを確認できました。

---

## 次回について
次回[（第７回）](https://qiita.com/turupon/items/a7c5459028b142ee6839)以降は、分析結果を累積しておき PowerAppsアプリケーション からその累積情報を取得する機能を 数回にわたって記載していきます。

---

## 参考情報
以下の情報を参考にさせていただきました。感謝申し上げます。
[PowerAppsとflowで入力チェック処理](https://qiita.com/sukkyxp/items/bdeb6d214419a662448b)
[#PowerApps のJSON関数を使ったFlowへのパラメータ渡し](https://www.kwbtblog.com/entry/2019/06/14/022309)
[PowerApps から Flow を呼び出して応答をコレクションとして受け取る際の注意点](https://blog.engineer-memo.com/2018/08/25/powerapps-%E3%81%8B%E3%82%89-flow-%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%A6%E5%BF%9C%E7%AD%94%E3%82%92%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6/)