Azure Faceで感情認識してみよう

最近使ったので少し書いてみます。
初投稿なので、間違いや足りない部分が多々あるかもしれません。
優しく教えていただけると幸いです:girl_tone1:

Azure Faceは顔認証の印象が強かったのですが
感情認識ができるの面白いと思ったので感情認識に使ってみました。

#[Azure Face](https://azure.microsoft.com/en-us/services/cognitive-services/face/)
※pythonのSDKを使いました。

出来ること：顔検証、顔検出、感情認識
他にも似た顔を探す、同じ顔でグループ分けするなどあるようです。
この記事では顔検出、感情認識あたりを使います。

##1.Azure エンドポイントおよびキー用の変数を作成
これを書くと使えるようになります:ok_woman_tone1:

```
KEY = 'your_key'
ENDPOINT = 'your_endpoint'
face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))
```

##2.顔検出のMethodを呼ぶ
```
params = ['age','emotion']
result = face_client.face.detect_with_stream(  
             image
             , return_face_id=True
             , return_face_landmarks=False
             , return_face_attributes=params 
         )
```

基本的にデフォルトのまま、return_face_attributesだけFalseから変えました。
image： 今回は画像のストリームを渡す
return_face_id：　TrueにするとfaceIDを返してくれる
return_face_landmarks: 　Trueにすると返してくれる。顔のランドマーク
return_face_attributes　パラメータで渡した属性の情報を返してくれる。

今回はreturn_face_attributesにage,emotionを渡したので
対象の年齢、感情を返してくれます。



#UI的なの作る
カメラでボタン押して写真撮る→感情認識→結果表示できるようにしたい…:upside_down:
kivyを使って作ります。

##シンプルなkivyファイルを作る
[Emotion.py]

```
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

Builder.load_string("""
<MainWidget>:

""")

class MainWidget(BoxLayout):
    pass
class EmotionApp(App):
    title = "E.A."
    def build(self):
        return MainWidget()

if __name__ == "__main__":
    EmotionApp().run()
```
画面↓
![E.A1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364550/33fc473e-a8e7-5697-04ef-d7c4057ccb16.png)

真っ黒

##2.カメラとボタンを付ける。
[Emotion.py]

```
(略)

Builder.load_string("""
<MainWidget>:
    orientation: 'vertical'
    Camera:
        id: camera
        resolution: (640, 480)
        play: True
    Button:
        text: 'Capture'
        size_hint_y: None
        height: '48dp'
        on_press: root.capture()
""")

class MainWidget(BoxLayout):
    def capture(self):
        print('captured!')
(略)

```
↓画面(顔と背景が映らないように超雑に加工したので、参考程度ですが…)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364550/b0520fe5-8618-b72e-dba4-0423bc7266d9.png)


##顔検出のMethodを入れる
[Emotion.py]

```
KEY = 'your_key'
ENDPOINT = 'your_endpoint'
face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))   

 　　(略)
    def capture(self):
        texture = self.ids['camera'].texture
        nparr = np.fromstring(texture.pixels, dtype=np.uint8)
        reshaped = np.reshape(nparr, (480,640,4))
        ret,buf = cv2.imencode('.jpg', reshaped)
        stream = io.BytesIO(buf)

        params = ['age','emotion','hair']
        result = face_client.face.detect_with_stream(  
                     stream
                     , return_face_id=True
                     , return_face_landmarks=False
                     , return_face_attributes=params 
                 )
　　　(略)
```

##結果表示用のポップアップ
[Emotion.py]

```
　　　(略)
　　　　Layout = BoxLayout(orientation='vertical')
       faceatts = result[0].face_attributes
       Layout.add_widget(Label(text=("age: "+ str(int(faceatts.age)))))
       Layout.add_widget(Label(text="emotion: "))      
       Layout.add_widget(Label(text="anger: " + str(faceatts.emotion.anger)))
       Layout.add_widget(Label(text="contempt: " + str(faceatts.emotion.contempt)))
       Layout.add_widget(Label(text="disgust: " + str(faceatts.emotion.disgust)))
       Layout.add_widget(Label(text="fear: " + str(faceatts.emotion.fear)))
       Layout.add_widget(Label(text="happiness: " + str(faceatts.emotion.happiness)))
       Layout.add_widget(Label(text="neutral: " + str(faceatts.emotion.neutral)))
       Layout.add_widget( Label(text="sadness: " + str(faceatts.emotion.sadness)))
       Layout.add_widget(Label(text="surprise: " + str(faceatts.emotion.surprise)))

       popupWindow = Popup(title="Results", content=Layout, size_hint=(None,None),size=(400,400)) 
       popupWindow.open()
     (略)
```

##できた！
使ってみます。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364550/f1cf992b-cad8-afea-2228-f27881883b42.png)
ボタンをクリック！
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364550/172f56b1-a397-5875-ddba-a586ecb9d57c.png)
おお～
ちゃんと笑ってるのが伝わりました！年齢が…若くなってる…(笑):relaxed:
そのうちもうちょっと見た目にこだわりたい＆仕組みについて学びたいなと思いました:robot:
お読みいただいてありがとうございます！

```
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import cv2
import numpy as np
import io
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from kivy.uix.label import Label
from kivy.uix.popup import Popup
KEY = 'your_key'
ENDPOINT =  'your_end_point'
face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))
Builder.load_string("""
<MainWidget>:
    orientation: 'vertical'
    Camera:
        id: camera
        resolution: (640, 480)
        play: True
    Button:
        text: 'Capture'
        size_hint_y: None
        height: '48dp'
        on_press: root.capture()
""")

class MainWidget(BoxLayout):
    def capture(self):
        texture = self.ids['camera'].texture
        nparr = np.fromstring(texture.pixels, dtype=np.uint8)
        reshaped = np.reshape(nparr, (480,640,4))
        ret,buf = cv2.imencode('.jpg', reshaped)
        stream = io.BytesIO(buf)
        params = ['age','emotion']
        result = face_client.face.detect_with_stream(  
                    stream
                    , return_face_id=True
                    , return_face_landmarks=False
                    , return_face_attributes=params 
            )
        Layout = BoxLayout(orientation='vertical')
        faceatts = result[0].face_attributes
        Layout.add_widget(Label(text=("age: "+ str(int(faceatts.age)))))
        Layout.add_widget(Label(text="emotion: "))      
        Layout.add_widget(Label(text="anger: " + str(faceatts.emotion.anger)))
        Layout.add_widget(Label(text="contempt: " + str(faceatts.emotion.contempt)))
        Layout.add_widget(Label(text="disgust: " + str(faceatts.emotion.disgust)))
        Layout.add_widget(Label(text="fear: " + str(faceatts.emotion.fear)))
        Layout.add_widget(Label(text="happiness: " + str(faceatts.emotion.happiness)))
        Layout.add_widget(Label(text="neutral: " + str(faceatts.emotion.neutral)))
        Layout.add_widget( Label(text="sadness: " + str(faceatts.emotion.sadness)))
        Layout.add_widget(Label(text="surprise: " + str(faceatts.emotion.surprise)))

        popupWindow = Popup(title="Results", content=Layout, size_hint=(None,None),size=(400,400)) 
        popupWindow.open()
        
class EmotionApp(App):
    title = "E.A."
    def build(self):
        return MainWidget()

if __name__ == "__main__":
    EmotionApp().run()


```