【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に縮小させました。
フォルダ内の画像を一括リサイズする方法は、下の記事に書きました。
今回は、手作りパンの画像を識別させてみました。
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ファイルが作成されます。
宿題
大体、思い通りのプログラムができましたが、惜しいのは一部文字化けしている所。
これはKakigori。上に棒線がある(Macron) o が文字化けしました。
これはChe(ベトナムのスイーツ・チェー)。上に点(Acute Accent)がある e が文字化けしました。
encoding='utf-8'にしても直らず。
この記事が気に入ったらサポートをしてみませんか?