見出し画像

【Vision Kit】複数枚の料理写真の識別をする

はじめに

Vision Kitのプログラム、dish_classification.pyは、料理の写真を見せると何の料理か識別してくれます。

まず、visionフォルダに移動します。

cd ~/AIY-projects-python/src/examples/vision

識別させたい画像を同じフォルダに入れます。データの移動はWinSCPが便利です。

下記のコマンドで実行します。

./dish_classification.py --input image.jpg

スマホで撮った写真(3MBくらい)をそのまま識別させると、データが重くて強制終了してしまいます。

強制終了

そのため、画像は1/4に縮小させました。

フォルダ内の画像を一括リサイズする方法は、下の記事に書きました。

今回は、手作りパンの画像を識別させてみました。

bread01_light

Result 0: Mochi (prob=0.201294)

(餅…。breadと言って欲しかったのですが…。)

しかし、このプログラムは画像1枚ずつしか識別できません。30枚の料理の写真を識別しようとすると、コマンドを30回実行し、結果も30回コピペしなければなりません。そこで、一気に複数枚の写真の識別をするプログラムを作成してみました。

プログラムを実行するのは、ラズパイのThonny。修正も実行もラクです。

元のプログラム

まずはdish_classification.pyのプログラムを確認します。これがベースになります。

一番最初の17行目は

import argparse

これはコマンドラインの解析をするモジュールです。今回は使用しません。

次の18行目は、画像処理ライブラリPillow(PIL)をインポートします。画像を縮小する際にも、このモジュールを使いました。

from PIL import Image

28行からwith文が始まり、画像ファイルを読み込み、識別をするようです。

複数の画像ファイルを扱う

画像を1/4にする時に参考にしたサイト↓

files = glob.glob('./(フォルダ名)/*.jpg')

この、フォルダ内のjpgの一覧をリストにする技を使います。

glob.glob(pathname)は、pathnameにマッチするパス名のリストを返します。

同じディレクトリ (~/AIY-projects-python/src/examples/vision) 内の "images_quarter"フォルダ内にあるjpgの一覧をリストにして、一つずつ出力してみます。

import glob
files = glob.glob('./images_quarter/*.jpg')
for i in files:
    print(i)

これと、元のプログラムを組み合わせれば、複数ファイルの識別ができそうです。

並び順がバラバラなので、ソートします。

files.sort()

結果にファイル名も付けたいですが、このままではパス名なので長いです。ファイル名だけにしたいので、区切り文字を "/" にしてsplitメソッドで区切ってリストにし、インデックス[2]だけ取り出します。


CSV出力

結果をCSV出力したいので、pandasを使います。Vision Kitのラズパイにpandasをインストールします。

pip install pandas

ではうまくいかず、途中まで進んだところで動かなくなりました。

sudo apt-get install python3-pandas

ならインストールできました。

to_csv()メソッドでは、ヘッダーとインデックスが不要なので、header=False, index=Falseにしました。

完成したプログラム

手順としては、
①1/4に縮小した画像を入れたフォルダ(今回の例では "images_quarter" というフォルダ名)を用意し、WinSCPを使ってVision Kitに送る。
②プログラムを実行する

これが完成したプログラムです。47枚の画像を識別するのに12分かかりました。

from PIL import Image
import glob
import pandas as pd

from aiy.vision.inference import ImageInference
from aiy.vision.models import dish_classification


files = glob.glob('./images_quarter/*.jpg')
files.sort()

dish_list=[]

for f in files:
    dish_list_0=[]
    name=f.split("/")
    dish_list_0.append(name[2])
    with ImageInference(dish_classification.model()) as inference:
        image = Image.open(f)
        classes = dish_classification.get_classes(inference.run(image), top_k=5, threshold=0.1)
        for i, (label, score) in enumerate(classes):
            dish_list_0.append('Result %d: %s (prob=%f)' % (i, label, score))
    dish_list.append(dish_list_0)
    
df=pd.DataFrame(dish_list)
df.to_csv("dish_list.csv", header=False, index=False, encoding='utf-8')
    

結果が入ったCSVファイルが作成されます。

結果CSV
結果CSV 拡大

宿題

大体、思い通りのプログラムができましたが、惜しいのは一部文字化けしている所。

これはKakigori。上に棒線がある(Macron) o が文字化けしました。

Kakigori

これはChe(ベトナムのスイーツ・チェー)。上に点(Acute Accent)がある e が文字化けしました。

Che

encoding='utf-8'にしても直らず。




この記事が気に入ったらサポートをしてみませんか?