Microsoft Cognitive Service Face APIにローカル上の画像を投げる
dichikaさんのMicrosoft Cognitive Serviceを使った記事、APIに投げる画像はサーバ上にある必要がある、ということだが、リクエストボディのContent-Type
でapplication/octet-stream
を指定することでローカルファイルをサーバを経由せずに直接投げることができる。
こんな感じでやる。検証用の画像として、件のGlobal Tokyo.R集合写真を使う(メガネのおじさんたちがメガネのお姉さんになってくれやしないか… ) 。Ocp-Apim-Subscription-Key
に与えるAPIキーは各自が用意したものを使うこと。
library(purrr) library(httr) # 対象の画像のパスを指定する x <- "~/Desktop/oretachino_globaltokyo_r.jpg" # 幅5000pxに引き伸ばし base.url <- "https://westus.api.cognitive.microsoft.com/face/v1.0/detect" result <- httr::POST(base.url, body = upload_file(x), query = list(returnFaceAttributes = "age,gender,headPose,smile,facialHair,glasses,emotion", language = "en"), httr::add_headers(.headers = c(`Content-Type` = "application/octet-stream", `Ocp-Apim-Subscription-Key` = <api_key>))) %>% httr::content()
先述の通り、Content-Type
の値をapplication/octet-stream
に変更するのと、
readBin()
を使ってローカルファイルをバイナリとして読み込ませる指定するという話。
ご指摘いただきました。ありがとうございます。
@u_ribo readBin(x, "raw", https://t.co/KtwoSQdNrQ(x)$size) の部分は、upload_file(x) でいけるはず。readBinだといちどメモリ上にファイルを読み込んでから送るけど、upload_fileは裏側でcurlがやってくれるので
— Hiroaki Yutani (@yutannihilation) 2017年4月5日
これらのアップロードにおいては,データはサーバにストリーミングで送信されます.データがRにチャンクとしてロードされ,リモートサーバに送られるのです.したがってメモリに収まらない大きなファイルもアップロードすることができます.
結果について確認しておくと、メガネ率は少し異なっている。画像のサイズが違うのだろうか。SwimmingGogglesつけてる人誰や…
result %>% map("faceAttributes") %>% map_chr("glasses") %>% table()
## .
## NoGlasses ReadingGlasses SwimmingGoggles
## 18 12 3
Enjoy!