チョコボール統計

チョコボールの秘密を統計解析で明らかにしていく。おもちゃのカンヅメ欲しい。

チョコボール画像からチョコボールの個数を自動計測してみる

【update:2021/03/31】 ソースコードの全面的な更新に伴って、解説記事も書き直しました。本記事は記述に不足がありますので、改訂版を参照ください。

chocolate-ball.hatenablog.com

【update:2021/03/25】 本記事で掲載しているソースコードに一部不足がありました。修正して整理したソースコードを以下のGithubリポジトリにupしています。

github.com

概要

  • 当ブログではこれまで、チョコボールを手動で計測してきました
  • しかし、毎回チョコボールの数を数えるのはめんどくさい
  • そこで、画像から自動でカウントさせよう(チョコボールに特化した一般物体認識のモデルを使ってカウント)
  • Faster R-CNNをfine tuneしたところ、粒が密集した画像でもそれぞれの粒を認識できていそう!すごい!

【トップに戻る】

はじめに

当ブログのメインコンテンツは、ピーナツ味のチョコボールの計測です。 重さを測ったり、個数を数えたりしているのですが、従来、それらは全て手動で行われています。

一方、画像処理分野を発端として、深層学習(Deep Learning)の多方面での有効性が知られています。 (深層学習技術の進展はついていくことすら難しいレベルでどんどん進んでいますね。。。)
特に、一般物体認識(Faster R-CNN, YOLO等)は、専門に調査・研究していない人でもテレビ等で見たことがあるのでは無いでしょうか?

この一般物体認識ですが、ザクっと言うと、特定の物体が画像内のどこにいくつ存在するのかを認識するものです。 この技術を使えばチョコボールの個数をわざわざ数える必要がなくなるのでは無いでしょうか?! 毎回毎回数える時間コストを考えると、かなりの効率化が図れるような図れないような気がしてきました。

【トップに戻る】

問題設定

ということで今回は、 チョコボール画像からチョコボールの個数を自動で計測する仕組みを作ります。

データ

毎回の計測で、以下のような画像を撮影しています。

f:id:hippy-hikky:20180520000645j:plain:w300

スマートフォンのカメラを使って手動で撮影しています。 そのため、影(照明環境)や距離が一定ではありません。

アプローチ

深層学習の適用事例として有名なものの一つに「一般物体認識」というタスクがあります。 これは、画像の中に写っている複数の物体を個別に認識する技術です(下図参照)。

f:id:hippy-hikky:20180523000337p:plain:w300
一般物体認識の事例。この例では、人、車、馬を個別に認識している。犬は馬と誤認識しているが

この技術を応用し、画像内に写っているチョコボールを個別に認識することで、個数が計量できるというアプローチを取ります。

ただし、一般物体認識と言っても全ての物体を認識できるわけではなく、 予め学習した物体のみを認識できます。 当然、公開されている学習済みモデルではチョコボールを認識してはくれません。 そのため、独自の学習データセットを作成し、チョコボールが認識できるように追加学習(fine tune)することが必要です。

【トップに戻る】

前処理

ということで、まずは学習データセットを作ります。

アノテーションデータ作成

一般物体認識モデルを学習するためには、 学習データとして画像にチョコボールの位置を示す情報を付与したデータセットを作成する必要があります。 このデータセットのことをアノテーションデータセットと呼びます(下図参照)。

例えば、このような画像ファイルに対して

f:id:hippy-hikky:20180521231701j:plain:w300

この図のように、「どこ」に「何」があるのかを示すデータを作ります。

f:id:hippy-hikky:20180521225642p:plain:w300

アノテーションデータセットは、画像データ、物体位置座標(長方形の対角位置座標)のリスト、物体カテゴリのリストがセットで必要になります。 このデータを作るために、LabelImgというツールを利用しました。
使い方はgithubのページを見ればわかると思います。

なお今回は、上図のように、認識対象の物体カテゴリとして、 choco-ball(チョコボールの粒)とchoco-package(パッケージ画像)の2つの物体を認識するものとしました。

PascalVOC形式xmlデータのパース

LabelImgというツールでは、 アノテーションデータをPascalVOC形式のxmlファイルで出力できます。

このままでは学習用データセットにはならないので、xmlファイルを読みこんで必要な情報を抜き出す必要があります。 PascalVOC形式のxmlをパースする便利なライブラリは私がちょっと探したところ見当たらなかったので、 以下のように作りました。

xmltodictというxmlファイルをdict形式でパースするライブラリを使い、 画像データ(imgs)、バウンディングボックスの座標リスト(bboxs)、物体カテゴリIDのリスト(obj_ids)をnumpyオブジェクトで書きだしています。

【トップに戻る】

認識モデル

一般物体認識モデルは複数提案されていますが、今回はFaster R-CNNを使います。 Faster R-CNNについては、日本語での解説記事も多数あるのでここでは言及しません。

認識する物体として今回は、choco-ballとchoco-packageの2つだけを認識するようにしました。 今回のタスクにおいては、一般物体を認識する必要など無いのです。

Faster-RCNNの実装はChianerCVを使いました。 ChainerCVとはChainerベースの画像処理ライブラリです。 後ろにコードを載せていますが、かなり簡潔に書けます。

【トップに戻る】

学習実験

いよいよ学習です。

実験設定&コード

今回の実験では、学習データとしてチョコボール画像22枚を用意しました。 (画像自体はもっとあるのですが、アノテーション作業が大変だったので。。。) このデータを8:2で分割し、学習データと評価データに分けました

  • 学習データ:17ファイル
  • 評価データ:5ファイル

学習係数などのパラメータはChainerCV公式exampleの設定をそのまま使いました。

コードは以下の通りです。 ChainerCVのexampleを ほぼほぼコピーさせてもらっています。

4セル目から6セル目でnumpyオブジェクトで保存した画像データ、バウンディングボックス座標リスト、物体カテゴリIDリストを 読み込んでいます。
読んだデータは、ChainerCVで扱いやすいようにTupleDatasetという形式のデータにしています(7セル目)。

9セル目でFasterRCNNのオブジェクトを作っています。 引数で今回認識対象とする物体(choco-ballとchoco-package)の指定をしています。 また、pretrainedmodelには、imagenetを指定します。 独自データで学習する際には、imagenetを指定する必要があるらしいです。

optimizerやiteratorはほぼexampleの通りです。

17〜21セル目でextentionの指定をしています。 公式exampleではiteration数でモデルの書き出し等設定していましたが、 epoch数で制御したほうが分かりやすかったのでepochで規準を作っています。

学習結果

上記のnotebookの23セル目に学習曲線(lossカーブ)がありますが、 20epoch学習させてみた結果です。 想定通りlossが落ちたように見えます。

f:id:hippy-hikky:20180523002647p:plain

もう少し学習させても良さそうですが、一旦これで評価してみます。 notebookの24セル以降が評価用のコードです。

評価用の5データのチョコボール数を算出したところ、 MSE(平均二乗誤差)が1なので、平均1個の誤認識があるようです。
これで十分な精度かどうかというと、、、ちょっと微妙かな。。。 (正確にはcross-validation必要)

試してみる

とにかく、学習したモデルを使ってチョコボールの認識をしてみましょう。 アノテーションをつけていない画像を入力して結果を見てみます。

うまく行った例

1枚目はそれぞれの粒がばらついているので簡単そうです。 2,3枚目はかなり密集していますが、それでもそれぞれの粒を認識できているようです。

f:id:hippy-hikky:20180523004801p:plain

f:id:hippy-hikky:20180523004831p:plain

f:id:hippy-hikky:20180523004850p:plain

検出ミスがあった例

やはり、密集していると見落としがちなようです。 3枚目の歪な形の物も見落としています。

f:id:hippy-hikky:20180523005156p:plain

f:id:hippy-hikky:20180523005233p:plain

f:id:hippy-hikky:20180523005127p:plain

【トップに戻る】

まとめ

22枚のデータを使ってFaster R-CNNをfine tuneしてみました。 結果としては、チョコボールの粒が密集した画像でも正しく粒を認識できているものがあるので、 この仕組みは有望だと感じます。 しかし、評価データで定量的に誤差を計算すると、平均1粒の計数ミスが生じるようで、まだ実用的というのは難しいかもしれません。

評価に関しては、評価データが5つしか無いのでcross-validationが必要です。 今回ざっくりと作ってみたところ有効そうな結果が見えてきたので、 データをもっと作り、また、cross-validationによって正確な評価をしてみようと思います。(今後の課題)

そういえば、粒のカウント工数を減らすことが目的だったんですが、、、 なかなか手間が減らなさそう(汗)

【トップに戻る】

参考資料

【トップに戻る】

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

森永製菓 チョコボール<ピーナッツ> 28g×20箱

森永製菓 チョコボール<ピーナッツ> 28g×20箱

  • 発売日: 2016/03/01
  • メディア: 食品&飲料

第62回 チョコボール計測

今日の計測報告です。
大人買いチョコボール開封の続きです。

これが

こうなりました。

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-22 2018-11-01 34.389 4.931 17 小山工場 スーパー(さいたま市 なし 29.458 1.733
2018-05-22 2018-11-01 34.645 4.919 16 小山工場 スーパー(さいたま市 なし 29.726 1.858
2018-05-22 2018-11-01 33.897 4.893 16 小山工場 スーパー(さいたま市 なし 29.004 1.813
2018-05-22 2018-11-01 34.428 4.89 17 小山工場 スーパー(さいたま市 なし 29.538 1.738

今回はエンゼルさん現れませんでした。

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 179
銀のエンゼル出現数 4
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.387 31.487 29.460
個数 14.000 16.000 20.000 16.425

f:id:hippy-hikky:20180522231151p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 103
銀のエンゼル出現数 6
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.21%、上側が10.84%という結果です。
f:id:hippy-hikky:20180522231227p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.05%、上側が3.07%という予測になっています。
f:id:hippy-hikky:20180522231249p:plain

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

第61回 チョコボール計測

今日の計測報告です。
同僚から4箱もらいましたので開封します。

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-19 2018-10-01 34.16 4.773 15 小山工場 ドラックストア(横浜市 なし 29.387 1.959
2018-05-19 2018-11-01 34.691 4.852 15 小山工場 ドラックストア(横浜市 なし 29.839 1.989
2018-05-19 2018-11-01 34.205 4.879 15 小山工場 ドラックストア(横浜市 なし 29.326 1.955
2018-05-19 2018-10-01 35.001 4.769 16 小山工場 ドラックストア(横浜市 なし 30.232 1.889

今回はエンゼルさん現れませんでした。

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 175
銀のエンゼル出現数 4
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.385 31.487 29.461
個数 14.000 16.000 20.000 16.423

f:id:hippy-hikky:20180519233450p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 99
銀のエンゼル出現数 6
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.29%、上側が11.61%という結果です。
f:id:hippy-hikky:20180519233528p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.06%、上側が3.10%という予測になっています。
f:id:hippy-hikky:20180519233551p:plain

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

第60回 チョコボール計測

今日の計測報告です。
お菓子のまちおかで大人買いしたチョコボール開封の続きです。

これから、

4箱開封しました。

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-16 2018-11-01 34.49 4.883 17 小山工場 スーパー(さいたま市 なし 29.607 1.742
2018-05-16 2018-11-01 34.25 4.876 16 小山工場 スーパー(さいたま市 なし 29.374 1.836
2018-05-16 2018-11-01 34.321 4.909 14 小山工場 スーパー(さいたま市 なし 29.412 2.101
2018-05-16 2018-11-01 34.785 4.909 16 小山工場 スーパー(さいたま市 なし 29.876 1.867

今回はエンゼルさん現れませんでした。

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 171
銀のエンゼル出現数 4
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.384 31.487 29.456
個数 14.000 16.000 20.000 16.450

f:id:hippy-hikky:20180516233908p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 95
銀のエンゼル出現数 6
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.50%、上側が12.22%という結果です。
f:id:hippy-hikky:20180516233944p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.05%、上側が3.13%という予測になっています。
f:id:hippy-hikky:20180516234005p:plain

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

第59回 チョコボール計測+おまけ

今日の計測報告です。
昨日とは別の同僚から2箱もらいました。

この同僚、同僚の中では最もたくさん購入してもらっているのに、 未だにエンゼルが1枚もあたっていません。
今回はどうなるでしょうか?

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-15 2018-12-01 34.473 4.881 19 小山工場 コンビニ(千代田区 なし 29.592 1.557
2018-05-15 2018-12-01 34.308 4.88 18 小山工場 コンビニ(千代田区 なし 29.428 1.635

今回はエンゼルさん現れませんでした。 この同僚の連続ハズレ記録更新中です。

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 167
銀のエンゼル出現数 4
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.383 31.487 29.453
個数 14.000 16.000 20.000 16.467

f:id:hippy-hikky:20180515234217p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 91
銀のエンゼル出現数 6
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.48%、上側が12.59%という結果です。
f:id:hippy-hikky:20180515234258p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.05%、上側が3.38%という予測になっています。
f:id:hippy-hikky:20180515234326p:plain

おまけ:購入者毎のエンゼル出現率予測

chocolate-ball.hatenablog.com

この記事で、購入者ごとの運の違いが出るのか?という分析をしてみました。 (実際は、データが増えれば平均に回帰していくはずなので、購入者毎の違いは出ないはず)
あの記事以降、 同僚AとBから追加してもらったので、改めて最近の状況を見てみます。 (最近だと、58回の計測では同僚B、今回は同僚Aからもらいました)

データ

購入数が多い、同僚A、B、筆者の3人分の計測データ数です。 カッコの中は銀のエンゼルの数です。
同僚A、未だエンゼル現れず!

購入者 2018-04-10 2018-04-22 2018-05-14
同僚A 8(0) 20(0) 22(0)
同僚B 6(1) 9(1) 16(2)
筆者 22(1) 32(1) 42(4)

出現確率予測結果

手法やコードについては上記の記事を参照ください。

まず、4/22時点の結果です。同僚Aの運のなさが現れていましたね。

f:id:hippy-hikky:20180423000308p:plain
2018-04-22時点の予測結果。購入数が多い3人の結果だけに限定。

次に、最近の結果を載せます。

f:id:hippy-hikky:20180516000023p:plain
2018-05-15時点の予測結果。

最近のエンゼルラッシュのおかげで私の予測分布が同僚Bと同じようになってきましたね。

そして、同僚Aの予測分布について、0付近への偏りが凄い!

ということで、同僚Aの運の無さがさらに際立ってきたという結果でした。

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

森永製菓 チョコボール<ピーナッツ> 28g×20箱

森永製菓 チョコボール<ピーナッツ> 28g×20箱

第58回 チョコボール計測

今日の計測報告です。
同僚から4箱もらいました。

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-14 2018-11-01 34.13 4.795 16 小山工場 ドラックストア(横浜市 29.335 1.833
2018-05-14 2018-11-01 34.001 4.871 16 小山工場 ドラックストア(横浜市 なし 29.130 1.821
2018-05-14 2018-11-01 34.352 4.894 16 小山工場 ドラックストア(横浜市 なし 29.458 1.841
2018-05-14 2018-11-01 34.036 4.871 17 小山工場 ドラックストア(横浜市 なし 29.165 1.716

今回もエンゼルさん現れてくれました! 連続!!

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 165
銀のエンゼル出現数 4
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.382 31.487 29.452
個数 14.000 16.000 20.000 16.442

f:id:hippy-hikky:20180514211055p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 89
銀のエンゼル出現数 6
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.77%、上側が12.54%という結果です。
f:id:hippy-hikky:20180514211140p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.03%、上側が3.12%という予測になっています。
f:id:hippy-hikky:20180514211201p:plain

銀のエンゼル、思ったよりも出ますね。 今の予測分布の期待値としては、7%超えちゃいます。

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

第57回 チョコボール計測

前回記事で購入した大人買いチョコボールの開封の続きです。

今日も4箱開封しました。

計測結果

date best_before weight box_weight number factory shop angel net_weight mean_weight
2018-05-12 2018-11-01 34.367 4.874 14 小山工場 スーパー(さいたま市 なし 29.493 2.107
2018-05-12 2018-11-01 34.223 4.875 18 小山工場 スーパー(さいたま市 なし 29.348 1.630
2018-05-12 2018-11-01 34.102 4.872 18 小山工場 スーパー(さいたま市 29.230 1.624
2018-05-12 2018-11-01 34.321 4.889 17 小山工場 スーパー(さいたま市 なし 29.432 1.731

今回、エンゼルさん現れてくれました!

これで銀のエンゼル5個集まったので、おもちゃのカンヅメと交換ができます。

エンゼルの印刷の濃さもバラつきがあるような。 新たな分析ネタになるかも。

基礎集計

この集計はピーナツ味のチョコボールの集計結果です。

項目
計測データ数 161
銀のエンゼル出現数 3
金のエンゼル出現数 1
最小 中央値 最大値 平均
正味重量 28.913 29.383 31.487 29.457
個数 14.000 16.000 20.000 16.447

f:id:hippy-hikky:20180512101422p:plain この図は正味の重量のヒストグラムです。 赤い縦線が仕様(28g)を表しています。 青い太線で正規分布と仮定した最尤推定量をプロットしています。

エンゼル出現確率の予測

通常版のエンゼルの予測を行っていきます。 これまでの通常版パッケージの開封結果は次の通りです。

項目
計測データ数 85
銀のエンゼル出現数 5
金のエンゼル出現数 0

この結果を使ってベイズ推定によるエンゼルの出現確率推定を行います。

はじめに銀のエンゼルの出現確率の推定です。
90%信用区間(上下それぞれ5%)は、下側が3.24%、上側が11.90%という結果です。
f:id:hippy-hikky:20180512101526p:plain

次に金のエンゼルの出現確率の推定です。 90%信用区間(上下それぞれ5%)は、下側が0.06%、上側が3.30%という予測になっています。
f:id:hippy-hikky:20180512101551p:plain

広告

Amazonの欲しいものリスト作ってみました。 チョコボールのカンパ募集中です。
チョコボールをカンパする

森永製菓  チョコボール<ピーナッツ>  28g×20箱

森永製菓 チョコボール<ピーナッツ> 28g×20箱