技術雑食系車好きの備忘録

今やってるもの:python・サーバ構築・blender

<python OpenCV>機械学習でランエボシリーズを見分けられるのか?

はじめに

Pythonの画像認識用ライブラリ「OpenCV」を使用した機械学習のお勉強中、ふと「初歩的な知識でニッチな違いも判別できるのか?」かと思い、試してみました。

題材は「詳しい人なら分かるが、詳しくない人には同じに見える」系のものが良いと考え、三菱自動車の「ランサーエボリューションV」と「ランサーエボリューションⅦ」にします。(以降「ランエボ5/7」)

機械学習した後、ランエボ5の写真とランエボ7の写真を仕分ける事ができれば成功です。

プログラム

  1. ランエボ5と7の写真を読み込ませてsavファイルを出力
  2. savファイルを読み込んだ上で用意されたランエボの写真を読み込み、判別させる

というプログラムを組みます

1.ランエボ5と7の写真を読み込ませてsavファイルを出力

Excelの設定ファイルから学習用の情報を読み込み、画像を読み込んで学習、ファイル出力するプログラムです

>01.ImageLearning.py

import os
import cv2
import glob
import pandas as pd
from sklearn import svm
import pickle

current_dir = os.getcwd()
labels = []
images = []
# 設定ファイルの読み込み
df = pd.read_excel("リスト.xlsx")

for index, row in df.iterrows():
    # 画像を読み込むフォルダを指定
    image_folder = str(row["No"])+"."+str(row["シリーズ名"])
    image_path = os.path.join(current_dir, image_folder)
    os.chdir(image_path)

    # フォルダ内の画像ファイルを取り出し
    for file in glob.glob("*.JPG"):
        # 画像を学習しやすいように加工
        img = cv2.imread(file)
        img = cv2.resize(img, (64, 64))
        img = img.flatten()

        # ラベルと画像をリストに追加する
        labels.append(row["シリーズ名"])
        images.append(img)
    print("Log  事前準備完了 : "+image_folder)
os.chdir(current_dir)
# 学習モデルを作成、学習
model = svm.SVC(decision_function_shape='ovr')
model.fit(images, labels)

# 相関を表示
print(model.score(images, labels))
# 学習データをファイルに保存
pickle.dump(model, open("model.sav", "wb"))
2.写真を読み込み、判別

1で出力したsavファイルを使用して、画像を判別させるプログラムです
判別結果はコンソールに出力します

>02.ImageJudgement.py

import cv2
import glob
from sklearn import svm
import pickle
#学習モデルの読み込み
model = pickle.load(open("model.sav", 'rb'))
#フォルダ内の画像ファイルを取り出す
for file in glob.glob("*.JPG"):
    img = cv2.imread(file)
    #画像を学習しやすいように加工する
    img = cv2.resize(img, (64, 64))
    img = img.flatten()
    print(file,"判定結果"+str(model.predict([img])))

事前準備

①.設定ファイルのExcel
中身はこんな感じ、Noとシリーズ名を組み合わせて読み込み先フォルダを指定、シリーズ名は後の画像判定の回答にも使用します
置き場は1のプログラムと同じフォルダです

②.学習用画像の用意
1のプログラム置き場のサブフォルダ内に各ランエボ写真を同じ枚数配置
写真の角度、カラーは適当に

ランエボ5用フォルダ

ランエボ7用フォルダ

③.判別対象の画像用意
2のプログラムと同じフォルダに、ランエボ5と7の画像を4枚づつ用意
色は揃えて角度は適当に

実行結果

実際にやってみます
①.画像読み込み、savファイル出力実行結果

(base) C:\Users\USER\python\sample_ImageLearn\01.Learning>python 01.ImageLearning.py
Log  事前準備完了 : 1.エボ5
Log  事前準備完了 : 2.エボ7
1.0

末尾の「1.0」は、教本曰く「学習結果の妥当性(目安」だそうで、別途勉強してみます

②.画像認識、識別実行結果
①の実行で生成した「model.sav」ファイルを、写真読み込み・判別用プログラム格納先にコピーして実行

(base) C:\Users\USER\python\sample_ImageLearn\02.Judgement>python 02.ImageJudgement.py
01.evo5.JPG 判定結果['エボ5']
02.evo5.JPG 判定結果['エボ7']
03.evo5.JPG 判定結果['エボ7']
04.evo5.JPG 判定結果['エボ7']
05.evo7.JPG 判定結果['エボ5']
06.evo7.JPG 判定結果['エボ7']
07.evo7.JPG 判定結果['エボ7']
08.evo7.JPG 判定結果['エボ7']

結果

結果は以下の通り、正答率は50%でした。

画像 正解 Python側答案 結果
1枚目 エボ5 エボ5 正解
2枚目 エボ5 エボ7 不正解
3枚目 エボ5 エボ7 不正解
4枚目 エボ5 エボ7 不正解
5枚目 エボ7 エボ5 不正解
6枚目 エボ7 エボ7 正解
7枚目 エボ7 エボ7 正解
8枚目 エボ7 エボ7 正解

うーん微妙...まあ初めての機械学習としては及第点でしょうか。
今後学習する画像の枚数を増やしたり、ランエボ7寄りの回答なのでランエボ5の画像バリエーションを増やしたらまた違う結果になるかもです。

精度が上がれば、フェアレディZZ33Z34型、色んな車のエンジンルームを比べるのも面白いかと思います。
ひとまずは満足。