料理ジャンル分類AIの作成 (その１)

# 背景
私は昨年のハッカソンにて、AIを用いたレストラン・居酒屋のレコメンドエンジンを開発しました。
https://github.com/ImagawaKosuke/AI_hack
<br>具体的には、以下の手順で操作をします。
１．レストランを「駅名」「食べたいもの」「費用」を設定する
※任意で画像検索すると、AIがジャンルをレコメンドします。<br>ハッカソンでは、

２．任意で「お酒の種類」と「表示件数」「検索範囲」など諸々設定する
この画像は、レストランなどを検索する際の画面です。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226429/c158f799-0242-13fb-93e8-d69c239580e9.png" width="400">

３．「検索」を押す

４．そうすると、出力したい分のレストランの情報を出すことができます。
「住所」や「営業時間」、「Chat-GPTによる口コミ生成」など<br>ユーザーにとってレストランを探しやすい情報を載せます。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226429/33c9c6ae-15a0-49ce-5fdd-f4a25701fb83.png" width="400">

## 使用技術
このアプリケーションの使用技術はこのような感じです。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226429/43935e53-c2de-88ac-9d30-e473d6c1d127.png" width="400">

## アプリケーションの目的
・容易にレストランを見つける
・画像や気分から店を見つける
・こだわりにあったレストランを見つける

## ターゲット
・打ち上げや同窓会を行う場所を探す人
・ランチや飲み会に行く人
・二次会をしたい人

## 利点・欠点
### 利点
・検索件数を少なくできる
・キャッチコピーを食べ物のこだわりに合わせる
・クイック検索が豊富なジャンルで検索する

### 欠点
・半自動的な画像認識
・UIの改善
・OpenAIのapiの有料化
・Firebaseによる会員登録機能の付与

## 改善案
参加したハッカソンの目的は、AIのツールを使用して開発することです。<br>
なので、口コミ生成はChat-GPT API, 画像検索はCloud Vision APIを使用しました。

現在は、このアプリケーションの改善を行っています。具体的には、以下の問題があるからです。
・OpenAIのapiの有料化
・Google Visionによる識別結果

Google Visionではこのような欠点がありました。
例えば、「ナポリタン」の写真を入力した際、イタリアンではなくスパゲッティと出力されました。なぜならホットペッパーAPIでは、イタリアンや中華料理などジャンルを選択して店を探す必要があります。しかし、スパゲッティやラーメン、ソフトクリームなどユーザーの食べたいものを優先して店を探すことは難しいと考えられます。そこで半自動的にはなるが、「スパゲッティ」や「ピザ」といったイタリアン料理に関係ある結果が出力されたら「イタリアン」と出力するようにコードを記述しました。
しかし、その場合はコード数が長くなるので、コード数を削減する際、料理ジャンル分類AIを提案する。

そこで、以下のようにアプリケーションを改善します。
・CyberAgentLLMによる口コミ生成
・料理ジャンル分類AIの開発

# 開発段階
このように、料理ジャンルをレコメンドするAIを作成しています。
１．知人・個人のカメラロールから料理画像を収集
２．拡張子・サイズの変更
３．低画質から高画質に変換
４．正解データの作成
５．深層学習モデルの適用

この記事では、1. 知人・個人のカメラロールから料理画像を収集 ~ 3. 拡張子・サイズの変更まで伝えます。

# 1. 知人・個人のカメラロールから料理画像を収集

まず、深層学習を行うにあたり、料理画像を収集し、<br>機械学習で適用できるように正方形にトリミング・切り取りをしました。

収集の仕方は２パターンあります。
１．定食から食べ物を収集: 複数の料理が載っている写真を料理の数複製し、<br>

一例として本モデルで使用するとんかつ定食を挙げます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226429/3b177b76-aafb-a38f-d401-a838480f740f.png" width="500">

手動で料理を抽出すると、皿の中にある料理を抽出することができました。

２．普通のトリミング作業
元画像のアスペクト比が１：１ではない画像を正方形に修正しました。

上記の作業を行うと、計600枚の画像を収集しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1226429/447c752c-6c09-5ea3-0cbd-0ea33985d6c2.png" width="300">


# ２．拡張子・サイズの変更
１．を通して学習で必要となる画像を収集しました。<br>また、画像ごとに拡張子・サイズが違うため、pythonを通して修正します。

このようなディレクトリで作業をします。
```
Food_recognition
    ├─Input #学習で使用する画像(まだ使わない)
    ├─source #スマホから画像を入れたディレクトリ
    └─resized #リサイズ後の画像
```

まず、sourceフォルダーにスマホ経由で600枚の画像を入れます。

次、Food_recognitionにディレクトリ移動して画像のファイル数を確認します。
```Python
#ファイル数を確認
import os
DIR = './source'
print(len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))])) #ファイル数を確認

```

600と出力されると大丈夫です。
このサイトを参照しました。
https://qiita.com/john-rocky/items/32909820f99486afee07

それから、拡張子をpngに統一しました。
```Python
import glob
kakucho = []
files = glob.glob("source/*") #すべての画像を収集
for i in files:
  kakucho.append(i.split('.')[-1]) #拡張子を抽出
  
kakucho = set(kakucho) #拡張子だけを出力 600枚分から4個分の拡張子を格納
print(kakucho) #{'HEIC', 'PNG', 'JPG', 'jpeg', }と出力したら正解
```

一部、HEIC画像が含まれるため、HEIC画像をpngに変換します。<br>以下のコードで変換します。
```Python
from PIL import Image
import pillow_heif

#HEICからpngに変換
def conv(image_path):
    new_name = image_path.replace('HEIC', 'png')
    heif_file = pillow_heif.read_heif(image_path)
    data = Image.frombytes(
        heif_file.mode,
        heif_file.size,
        heif_file.data,
        "raw",
        heif_file.mode,
        heif_file.stride,
        )
    data.save(new_name, "png")

import glob
lst = glob.glob("*.HEIC")
for l in range(0,len(lst)):
    conv(lst[l])
```

sourceディレクトリ内で実行したら、HEIC画像も含まれつつpng画像を生成しました。
しかし、一部画像は失敗しました。その際はコンバーターで画像を変換しました。

参考にしたサイトです。
・「bigcat88/pillow_heif」https://github.com/bigcat88/pillow_heif
・「HEICからPNGへのコンバーター」https://convertio.co/ja/heic-png/

収集後、HEIC画像は削除してリサイズを行いました。
```Python
from PIL import Image

files = glob.glob("source/*.png") #ファイルを抽出
for i in range(1,len(files)+1):
  img = Image.open(files[i-1]) #画像を選択
  img_resize_lanczos = img.resize((256, 256), Image.LANCZOS) #リサイズ
  img_resize_lanczos.save('./resized/IMG_{0:05d}.png'.format(i)) #保存
```

以上、このように画像を収集しました。

# まとめ
私の趣味は旅行、友人と居酒屋行くことなので、このアプリケーションを実用化できたらいいなと思っています。さらに、ハッカソンで創出した作品は今後無駄にしないように、
改善する習慣をつけます。
今回、画質変換と深層学習を行う予定でしたが、Google Colab無料版のGPUの制限を超えました。なので、後日画質変換を行います。