Google Custom Search API と Microsoft Cognitive Services を使って misono の表情の割合を出して NetOffice で Excel にグラフ化した

2020/04/18

Microsoft Cognitive Services を使って何かやってみようと思い、散歩しながら考えた結果、Google Custom API を使って画像を検索して、その画像の表情を Microsoft Cognitive Services で取得して割合を確認した時の備忘録です。

画像を集める

まずは Google Custom Search API の準備を行います。 私は以前 Hubot で遊んでいる時に設定したことがあるのですが、全然覚えていなかったので、備忘録として詳しめに書きます。

1. プロジェクトを作ります(Google Custom Search API の準備)

  • 1-1. 「IAM と管理」の「全てのプロジェクト」 から、[プロジェクトの作成] をクリックします。

  • 1-2. 新しいプロジェクト名を入力します(少し時間がかかります)

  • 1-3. 画面が切り替わった後、[Custom Search API] をクリックします

  • 1-4. [有効にする] をクリックします

  • 1-5. [認証情報に進む] をクリックします

  • 1-6. 必要な認証情報の種類を「Custom Search API」に選択して、[必要な認証情報] をクリックします

  • 1-7. API キーをコピーしてメモ帳とかに貼り付けておいて、[完了] をクリックします

2. Custom Search Engine を作成します(Google Custom Search API の準備)

  • 2-1. CSE(Custom Search Engine)https://cse.google.com/cse/all の画面から [Add] をクリックする

  • 2-2. 検索するサイトに「www.google.co.jp/*」、言語を「日本語」と選択して [作成] をクリックします

  • 2-3. [コントロールパネル] をクリックします

  • 2-4. [検索エンジンID] をクリックして、表示された検索エンジン ID をメモ帳とかに貼り付けておきます

  • 2-5. 「画像検索」をオンに、検索するサイトを「追加したサイトを重視して、ウェブ全体を検索する」に選択します

3. Google Custom API を PowerShell で叩いてみる

早速 API を叩いて画像の URL を取得します。

$uri = 'https://www.googleapis.com/customsearch/v1?searchType=image&key={0}&cx={1}&q={2}&start={3}'

$result = Invoke-RestMethod -Uri (`
    $uri -f '手順 1-7 で取得した API キー', `
            '手順 2-4 で取得した検索エンジンID', `
            'misono', 1)
$links = $result.items.link

一度に 10 件の URL を取得できます。

つまり上記の例では、恐らく $links 内に misono の写真の URL が 10 個ゲットできているはず… (ゴクリ

画像から表情データを収集する

Microsoft Cognitive Services の Emotion API を使って表情データを取得していきます。

4. Microsoft Cognitive Services を使う準備

下記記事が判りやすいです。ありがとうございます!

5. Microsoft Cognitive Services の Emotion API で情報を取得

$EMOTION_API_KEY = '手順 4 で取得した Emotion API キー'
$uri = 'https://api.projectoxford.ai/emotion/v1.0/recognize'

# データを格納するハッシュを作ります
'anger', 'contempt', 'disgust', 'fear', 'happiness', 'neutral', 'sadness', 'surprise' | %{$scores.Set_Item($_, 0)}

# 先に取得したリンク分繰り返す
foreach($link in $links)
{
    $result = Invoke-RestMethod `
        -Uri $uri `
        -Method Post `
        -ContentType 'application/json' `
        -Headers @{'Ocp-Apim-Subscription-Key' = $EMOTION_API_KEY } `
        -body (ConvertTo-Json(@{'url' = $link}))

    # 写真が1人の時に値を合計します
    if($result.scores.Count -eq 1) {
        $scores.Clone() | %{$_.Keys} | %{$scores.$_ += $result.scores.$_}
    }

}

実行した結果はこのようになりました

$scores

Name                           Value
----                           -----
neutral                        3.698848848245151
surprise                       0.643928084988507
fear                           0.06122704455735687
sadness                        0.189069839999830918
disgust                        0.001162667252236
anger                          0.0045491115141025
contempt                       0.022837591950848
happiness                      4.37837686581

Excel でグラフ化する

数値だけみても、自然な表情か喜んでいる写真が多いのが判りますが、折角ですので手元の Excel でグラフ化してみたいと思います。

過去、COM を使ったり(PowerShell で Excel をどうのこうのすることに興味を持ってくれると嬉しい)、ClosedXML を使ったりして(PowerShell で ClosedXML を使って Excel ファイルを作成する) Excel ファイルを作っていましたが、今回は NetOffice を使ってグラフ作成を試してみたいと思います。

6. NetOffice の準備

  • NetOffice のダウンロードと展開
    CodePlex からダウンロードします

    ダウンロード後、適当な場所に展開します。私は今回 C ドライブ直下に展開しました。

  • ダウンロードしたライブラリにはセキュリティの観点からブロックが施されています ので 、ダウンロードした zip ファイルを右クリックしてプロパティを開き、ブロックの解除にチェックを入れて OK ボタンを押します

  • しかし、今回の方法だと .NET 2.0 ~ からのバイナリやドキュメント、ソースコードまで丸ごと入っていて、圧縮された状態で 150MB 程度、展開すると 950MB 程度になりましたので、NuGet が入っている環境なら NuGet から NetOffice.Excel を指定してインストールしたほうが良いかもしれません(未確認)。
    ■ 参考

7. 取得したデータを Excel に保存してグラフで表示する

本手順では、$xls.Visible = $true として Excel を表示させるようにしています。

コマンドを流すと一つ一つ Excel が動作すること確認でき、なかなか楽しいです。

是非、下記のコマンドをコピペでいいので一行づつ PowerShell で実行して頂けたらと思います。

[void][Reflection.Assembly]::LoadFile("C:\NetOffice 1.7.3\Toolbox Binaries\NetOffice.dll")
[void][Reflection.Assembly]::LoadFile("C:\NetOffice 1.7.3\Toolbox Binaries\OfficeApi.dll")
[void][Reflection.Assembly]::LoadFile("C:\NetOffice 1.7.3\Toolbox Binaries\ExcelApi.dll")
[void][Reflection.Assembly]::LoadFile("C:\NetOffice 1.7.3\Toolbox Binaries\VBIDEApi.dll")

$xls = New-Object NetOffice.ExcelApi.Application
$xls.Visible = $true

$book = $xls.Workbooks.Add()
$sheet1 = $book.Worksheets[1] # View シート用
$sheet2 = $book.Sheets.Add()  # Data シート用

$y = 1
$sheet2.Cells[$y++, 2].Value = '表情の割合'
@{
  anger    = 'o(`へ´)o プンプン!!'
  contempt = "┐('~`;)┌ ヤレヤレ"
  disgust  = '(´・д・`) ヤダ'
  fear     = "((;゚Д゚)ガクガクブルブル"
  happiness= 'ヾ(=^▽^=)ノ'
  neutral  = '( ・ _ ・ )'
  sadness  = '(´・_・`)'
  surprise = 'w( ̄▽ ̄;)wワオッ!!'
}.GetEnumerator() | %{$sheet2.Cells[$y, 1].Value = $_.Value; $sheet2.Cells[$y++, 2].Value = $scores.($_.Name);}

# 
$chart = ($sheet1.ChartObjects()).Add(10, 10, 500, 300)
$chart.Chart.ChartType = [NetOffice.ExcelApi.Enums.XlChartType]::xlPie
$chart.Chart.SetSourceData($sheet2.Range("A1:B9"))

# デスクトップに保存
$book.SaveAs("${HOME}\Desktop\hoge.xlsx")

#オブジェクトの破棄
$xls.Quit()

上記コマンドの実行結果は次になりました。


顔文字だと判りにくい… (おい)

考察

粗々ですが一通り試したいことはできました! Emotion API を使えば、ネットから笑顔の misono の写真を取得するという俺得なプログラムが書けそうです。

また、自分が写った過去の写真を Emotion API にかけることで、人生で一番楽しかった時が判るかもしれません(これは怖い)

今回初めて NetOffice を使ってみたのですが、Excel だけではなく、PowerPoint や Word も扱えるようですので、又何かあったら使ってみたいと思います。