fooddetection ~料理検知ライブラリの使い方~

以前、世界の料理の配色割合を調べていた時に画像から料理を抽出する作業が必要となったことがあった。
今回はその<strong>料理抽出作業</strong>をライブラリ化したので使い方をまとめてみた。
もし利用できそうな機会があれば是非利用してみて欲しい。

<h1>料理抽出作業とは</h1>
この記事で言う料理抽出作業とは一枚の料理画像から料理以外の要素をできるだけ排除し料理部分を残す作業のことである。

<img width="300" alt="中華.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/dafbd5b3-3dd8-44ee-f908-6dd9599ee491.jpeg">
↑ 料理抽出作業前画像
上の画像から料理部分だけを抽出し(背景などを削除したい)、下の画像のように背景など不要な部分を透明化させることを目的としている。

<img width="300" alt="中華検知.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/cf99abca-ce5c-bf7e-60c4-568234271a0d.png">


↑ 料理抽出作業終了後画像

<h1>fooddetectionライブラリでできること</h1>
長所：
・大量のデータを学習させずとも料理の部分を検知することが可能
・検知した部分以外の部分(背景など)を削除し、透明化することが可能

短所：
・AIではないので精度が悪い
・自動化できていない部分がある

<strong>料理部分だけ抽出したい場合のみ使えるライブラリとなっている。</strong>
AIを用いているわけではないので精度が悪かったり、手動でやらねばならない作業もあるが
ライブラリをインストールするだけで簡単に料理抽出が行えるので是非使ってみて欲しい。

<h1>ライブラリの使用方法</h1>
###前提
言語：Python3.7、Python3.8、Python3.9

```Bash:
$ pip install fooddetection
```
ライブラリをPython環境にインストール
https://pypi.org/project/fooddetection/

###手順①~必要なライブラリのインストール~

```Python:
from fooddetect import * 
# from fooddetect import show_contours,detect_food でもOK
```

###手順②~輪郭選択~
今回は下の中華を題材とする
<img width="300" alt="中華.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/dafbd5b3-3dd8-44ee-f908-6dd9599ee491.jpeg">

```Python:
show_contours('./images/中華.jpg')#引数には画像パスを入れる
```
引数に画像のパスを入力すると以下のように出力される。
<img width="400" alt="中華輪郭.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/f047e725-9aca-663b-6bdd-d68809f28358.png">

緑の楕円が料理の輪郭でこのライブラリでは緑の楕円を複数表示するよう設定している。
<strong>ユーザーは出力画像から適切な緑の楕円を選択する必要がある。
この選択でどこの部分を抽出するか決定するのでとても大事な作業になる。</strong>

####選択の仕方
①料理の部分と同じくらいの面積・形をしている楕円を見つける。
②①で見つけた楕円の面積、大きさが画像全体の楕円の中で大きい方から数えて何番目か考える。
→題材としている中華画像なら皿の縁である楕円が料理と同じサイズであり、その面積は大きい方から数えて<strong>二番目</strong>に大きいことがわかる。
以降、<strong>「手順②で選択した楕円の番号」</strong>という言葉が出てくるが、それは選択した楕円の面積が大きい方から数えて何番目になるのかと考えてもらいたい。
Ex>題材としている中華の画像であれば
<strong>「手順②で選択した楕円の番号」</strong> = <strong>2</strong> になる。

輪郭となる楕円を選択できたら次の手順③に進む!!!


###手順③~背景透明化~
手順③ではdetect_food関数を利用する。

```Python:
detect_food('./images/中華.jpg',2)#引数には画像パス、手順②で選択した楕円の番号を入れる
```
出力画像は以下のようになる。
<img width="300" alt="中華検知失敗.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/af729b42-312b-40fa-66b3-6ff5dd462c98.png">

一見、完成したと見えるかも知れないがよくみると皿の縁の楕円のところで抽出してくれていない、、、
この出力結果と手順②の出力結果と比較すると出力画像は番号1(一番大きい楕円)で切り抜いてしまっていることがわかる。
<strong>プログラミング上と目視で選択するものでは誤差が生じる時があるらしい、、、</strong>

####解決案・微調整
基本は手順②で目視で選択した番号でうまいこといくのだが、今回のように予期していない楕円で抽出されてしまうことがある。
その場合は、
<strong>手順②で選択した楕円の番号 ±１</strong>を引数に再度入れ直して微調整すると精度が向上するだろう

```Python:
detect_food('./images/中華.jpg',3)
```
出力画像は以下のようになる。
しっかりと皿の縁のところで切り取ってくれたので成功と言えるだろう。
もちろん抽出した画像も保存されている。
<img width="300" alt="中華検知.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/e24569d0-7081-b3f3-efcf-888343e2685d.png">


<h1>試しに他の画像でも実験</h1>
###① 題材画像：焼きそば
<img width="300" alt="焼きそば.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/02caa745-8cb2-fbc1-8a42-10c5b7fdb6fa.jpeg">

```Python:
from fooddetect import * 
show_contours('./images/焼きそば.jpg')#引数には画像パスを入れる
```
出力画像は以下になります。
<img width="400" alt="焼きそば輪郭.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/1d05fd74-2669-b393-209a-47d7ebc3e7ef.png">

今回は1番大きい緑の楕円が良さそうなので引数には1を代入

```Python:
detect_food('./images/焼きそば.jpg',1)#引数には画像パス、手順②で選択した楕円の番号を入れる
```
出力画像は以下になります。
<img width="300" alt="焼きそば検知失敗.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/93d667ac-99e9-60ea-ec0b-243d3b1411f6.png">

??????思ってたのと違う、、、
プログラミング上では右上の部分が一番大きいらしい。
<strong>手順②で選択した楕円の番号 ±１</strong>
右の上の緑の楕円の次に大きい場所と考えて2を引数に代入し再度実行

```Python:
detect_food('./images/焼きそば.jpg',2)
```
出力画像は以下になります。
少し背景も含まれてるけど精度はかなり向上した!!!完成!!!
<img width="300" alt="焼きそば検知.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691539/9c57c512-2c05-4675-ecc5-f2abdc5a2d0e.png">