Google Cloud Vision APIを使ってレシートの不健康度を色で表現する

これをやりたい。


レシートはこの間の飲み会のこれ。

これにGoogle Cloud Vision APIOCRを適用し、不健康そうなメニューに色をつけて可視化したい。

OCRをかけてみる

OCRをかけてみると、非常に優秀な結果が返ってくるがさすがにbounding boxはメニューごとに返ってきたりはしないためそのまま色付けしても全体に色付けすることになってしまう。

# getResult関数はhttp://d.hatena.ne.jp/dichika/20160223/p1 を参照のこと
> smp <- getResult(f)
> content(smp)$responses[[1]]$textAnnotations
[[1]]
[[1]]$locale
[1] "ja"

[[1]]$description
[1] "おまかせ酒の肴三種#8\n\850\n&#28799;鶏唐揚げ\n\650\n山菜天ぷら\n\900外\nさつま揚げ\n#600外\nブリ大根\n#850外\n煮穴子炙り\n\1.500外\nふぐ唐揚げ\n\900外\n0000000\n5500500-\n8696859\n"

[[1]]$boundingPoly
[[1]]$boundingPoly$vertices
[[1]]$boundingPoly$vertices[[1]]
[[1]]$boundingPoly$vertices[[1]]$y
[1] 54


[[1]]$boundingPoly$vertices[[2]]
[[1]]$boundingPoly$vertices[[2]]$x
[1] 209

[[1]]$boundingPoly$vertices[[2]]$y
[1] 54


[[1]]$boundingPoly$vertices[[3]]
[[1]]$boundingPoly$vertices[[3]]$x
[1] 209

[[1]]$boundingPoly$vertices[[3]]$y
[1] 424


[[1]]$boundingPoly$vertices[[4]]
[[1]]$boundingPoly$vertices[[4]]$y
[1] 424

画像を分割して対応する

ならば画像を分割して投げてやればいい。
今回は「揚げ」「天ぷら」という言葉が入っている場合を不健康なメニューと設定した。
結果はこうなる。

コードは以下の通り。
(getResult関数はhttp://d.hatena.ne.jp/dichika/20160223/p1 を参照のこと)

library("png")
library("abind")
f <- "receipt.png"
dat <- readPNG(f)
dat_res <- NULL
i <- 0
while((i+30) < dim(dat)[2]){
  # split
  trg_range <- seq(i,i+30)
  dat_tmp <- dat[, trg_range, ]
  # OCR
  f_tmp <- tempfile()
  writePNG(dat_tmp, f_tmp)
  ocr_tmp <- getResult(f_tmp)
  desc <- content(ocr_tmp)$responses[[1]]$textAnnotations[[1]]$description
  # convert
  if(grepl("揚げ|天ぷら", desc)){
    dat_tmp[, , 1] <- 0.5  
  }
  # combine
  dat_res <- abind(dat_res, dat_tmp, along = 2)
  i <- i + 30
}
writePNG(dat_res, "result.png")

今後の展望

今回は画像を決めうちで分割したが、この辺画像処理のテクニック使えば自動的に分割できるのかもしれない。
また、不健康なメニューも色々な言葉を設定できるだろう。
あらかじめメニューとエネルギー(kcal)を対応づけておけば、エネルギーに応じた可視化も可能になる。

なお、Google Cloud Vision APIは無料で使える回数に制限があるので注意してほしい。

Enjoy!!!