第2回:猫猫ちゃん判定アプリ作成へ
〇開発環境
・windows10
・python3.6
・PyCharm Community Edition 2017.1.5
・Android Studio
・xampp
〇第1回から
猫の顔を認識するための分類機作成にチャレンジしたが失敗。。。
仕方がなく既存の猫の顔用の分類機(openCVに初期で準備されている)を利用することにした
次回以降、自作分類機作成にチャレンジしてみたいし、作成できれば学習させることができる(まさにAI!)
画像を受け取り、猫の顔を認識できれば「cat」、認識できなければ「not cat」と返すようにしてみた
以下ソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
#!C:/Users/yuba\AppData/Local/Programs/Python/Python36/python.exe #!/usr/bin/python # -*- coding: utf-8 -*- import os import cv2 import sys import numpy as np import logging import types from PIL import Image import cgi import cgitb; cgitb.enable() import io, os, sys import requests # トレーニング画像 train_path = 'C:/Users/yuba/Desktop/catt' # テスト画像 test_path = 'C:/Users/yuba/Desktop/not_catt' # Haar-like特徴分類器 cascadePath = "C:/Users/yuba/Downloads/opencv/sources/data/haarcascades/haarcascade_frontalcatface.xml" faceCascade = cv2.CascadeClassifier(cascadePath) # 顔認識器の構築 for OpenCV 2 # ※ OpenCV3ではFaceRecognizerはcv2.faceのモジュールになります # EigenFace recognizer = cv2.face.createEigenFaceRecognizer() # FisherFace #recognizer = cv2.face.createLBPHFaceRecognizer() # LBPH #recognizer = cv2.face.createLBPHFaceRecognizer() # 指定されたpath内の画像を取得 def get_images_and_labels(path): # 画像を格納する配列 images = [] # ラベルを格納する配列 labels = [] # ファイル名を格納する配列 files = [] #for f in os.listdir(path): # 画像のパス #image_path = os.path.join(path, f) image_path = path # グレースケールで画像を読み込む image_pil = Image.open(image_path).convert('L') # NumPyの配列に格納 image = np.array(image_pil, 'uint8') # Haar-like特徴分類器で顔を検知 faces = faceCascade.detectMultiScale(image) if faces == tuple(): # 顔を 200x200 サイズにリサイズ #roi = cv2.resize(image[y: y + h, x: x + w], (200, 200), interpolation=cv2.INTER_LINEAR) # 画像を配列に格納 images.append(image) # ファイル名からラベルを取得 labels.append("not cat") # ファイル名を配列に格納 #files.append(f) else: # 検出した顔画像の処理 for (x, y, w, h) in faces: # 顔を 200x200 サイズにリサイズ roi = cv2.resize(image[y: y + h, x: x + w], (200, 200), interpolation=cv2.INTER_LINEAR) # 画像を配列に格納 images.append(roi) # ファイル名からラベルを取得 labels.append("cat") return images, labels def main(imagePath): test_images, test_labels = get_images_and_labels(imagePath) logging.debug("bbbbb") i = 0 while i < len(test_labels): logging.debug("ccccc") print("{") print("\"status\":\"OK\",") print("\"result\":\"" + test_labels[i] + "\"}") # テスト画像を表示 cv2.imshow("test image", test_images[i]) cv2.waitKey(300) i += 1 # 終了処理 cv2.destroyAllWindows() if __name__ == '__main__': print("Content-Type: text/plain") print() logging.basicConfig(filename='example.log', level=logging.DEBUG) try: form2 = sys.stdin.buffer.read() file = open("test.jpg", "wb") file.write(form2) file.close() except: logging.debug(str(sys.exc_info())) main('C:/xampp/htdocs/cat_image_analysis/test.jpg') |
〇せっかくなのでAndroidと連携
7月からandroidアプリの作成をやっていたので
①Androidで画像を選択
②pythonへ画像データを送信
③結果をJSONで返す
④Androidに結果を表示
の流れでやってみようと試みる。がどうやってPythonに画像データを送ればよいのか。。。
requestBodyに画像データを入れて送ってみた
1 2 3 4 5 |
File imageFile; Request request = new Request.Builder() .url(urlPath) .post(RequestBody.create(MediaType.parse("image/jpeg"), imageFile)) .build(); |
python側でRequestBodyから読み込み画像ファイルに書き込んでその画像で判別すれば行けるのではとやってみるも以下のソースではだめだった。。。
1 2 3 4 5 6 7 |
try: form2 = sys.stdin.read() file = open("test.jpg", "wb") file.write(bytearray(form2, 'utf-8', 'surrogatepass')) file.close() except: logging.debug(str(sys.exc_info())) |
ファイルへの書き込みは成功しているが画像として開けない。。。そもそもだが受け取るデータがこれだとstr型で受け取られる。それをbyteとして書き込んでいる。
受け取るときにbufferとして受け取り書き込んでみる
1 2 3 4 5 6 7 |
try: form2 = sys.stdin.buffer.read() file = open("test.jpg", "wb") file.write(form2) file.close() except: logging.debug(str(sys.exc_info())) |
画像として開けるようになった。これでAndroidとPythonの連携ができるようになった!!
〇今回のアプリの精度
既存の分類機を使っている且新たに学習していかないので猫画像でも猫じゃないとでた画像は今のままではずっと猫じゃない画像として認識される。
今後余裕があれば学習できるように改善していきたい。
今の時点の精度は
①正面を向き、口を大きく開いていない猫画像は猫と判定
②犬やサル、トラ、チータ、猫っぽい人などは猫じゃないと判定
参考
③トラ模様のヤマネコなど一部特殊な猫に関しては猫じゃないと判断されることも。。。
参考
④片方の目しか映っていない、顔がつぶれているなどの状態だと猫じゃないと判断される。
参考
〇今後
今回は既存の分類機を使って終わりなので分類機を作成および学習させていくことに挑戦していきたい。どんどん学習し、どんどん精度が上がっていく。
そのようなアプリ作成を次は挑戦してみたい!!(今回もそんなアプリを目指したが時間の関係上次回こそ!!)