コード10行で物体検出!? ImageAIを試してみた

シェアする

  • このエントリーをはてなブックマークに追加
スポンサーリンク

はじめに

タイトルに書いてあるのをみて皆さんはどのように感じたでしょうか?というのも、このタイトルは今回参考にしている海外のウェブサイトと同様のもので自分がこれを見たときに思わず気になってその記事を読んでしまいました。

これが次のサイトになります。

そこで扱われているライブラリImageAIが気になったので、今回実際に使って見てまとめて見ました。

記事のまとめ

この記事に書いてあることを簡単にまとめて見ます。

まずはじめに、コンピュータビジョンと物体認識についてこれまでの流れを簡単にまとめています。そして、物体検出を使用する新しい製品を作るには数多くの専門家やソフトウェアエンジニアが必要だが、理解と実用化の間には開きがあるということを問題としてあげています。

そして、その問題を解決するために、プログラマやソフトウェアエンジニアが最先端のコンピュータビジョンテクノロジを既存のアプリケーションや新しいアプリケーションに簡単に統合できるPythonライブラリImageAIを作ったという流れになっています。

そのあとは、ImageAIをどのように使うかを説明したものとなっています。

ImageAI

とりあえず実際に物体認識させてみる

まず、記事の通り実行して見たいと思います。こちらから“resnet50_coco_best_v2.0.1.h5”をダウンロードしてください。GoogleColaboratory上で実行する場合は、アップロードしておいてください。コードを見やすくするための空行を除けば、タイトル通り10行のコードとなっています。また、画像はImageAIGithubに入っている画像を用いました。リンクはこちら

from imageai.Detection import ObjectDetection 
import os 
execution_path = os.getcwd() 
detector = ObjectDetection() 
detector.setModelTypeAsRetinaNet() 
detector.setModelPath("resnet50_coco_best_v2.0.1.h5") 
detector.loadModel() 
detections = detector.detectObjectsFromImage(input_image="image3.jpg", output_image_path= "image3new.jpg") 
for eachObject in detections:
     print(eachObject["name"] , " : " , eachObject["percentage_probability"] )

結果がこちらになります。

表示がちょっと汚いですが、しっかり検出できてますね。とりあえずやって見たいという人にはいいかもしれません。なにせ、ここまででやったことはダウンロードと10行程度のコードをコピーするだけだったので。今回は、チュートリアルでやめておきますが、どこまでできるか次回くらいに試す予定です。

他にも画像に写る物体の予測と、動画の物体認識にもこのライブラリは対応しています。

画像に写る物体の予測

ImageAIは、次の4種類のネットワークに対応しています。

提供される4つのネットワークは、SqueezeNetResNetInceptionV3DenseNetがあります。

これらは、それぞれに応じて使用する必要のある個々のモデルファイルがあるため、必要なファイルを以下のリンクでダウンロードしてください。

  • SqueezeNet :(サイズ= 4.82 MB、予測時間:最速、適度な精度)
  • ResNet50 :(サイズ= 98MB、予測時間:高速、高い精度)
  • InceptionV3 :(サイズ= 91.6MB、予測時間:遅い、高い精度)
  • DenseNet121 :(サイズ= 31.6 MB、予測時間:遅い、精度が高い)

その後、次のプログラムコードで予測結果をみることができます。画像に関しては、こちらをダウンロードして解凍した後、Imageフォルダにある画像を次のコードと同じ階層にコピーしてください。そのとき、先ほどダウンロードしたモデルファイルも忘れずに同じ階層にコピーしといてください。

from imageai.Prediction
import ImagePrediction
import os execution_path = os.getcwd()
prediction = ImagePrediction() 
prediction.setModelTypeAsResNet() 
prediction.setModelPath(os.path.join(execution_path, "resnet50_weights_tf_dim_ordering_tf_kernels.h5")) 
prediction.loadModel() 
predictions, probabilities = prediction.predictImage(os.path.join(execution_path, "1.jpg"), result_count=5 ) 
for eachPrediction, eachProbability in zip(predictions, probabilities): 
   print(eachPrediction , " : " , eachProbability)

convertible  :  52.45957374572754
sports_car  :  37.612783908843994
pickup  :  3.17511223256588
car_wheel  :  1.8174994736909866
minivan  :  1.7487023025751114

from imageai.Prediction import ImagePrediction  
import os

このコードは、ImageAIライブラリとPythonのosクラスをインポートします。

execution_path = os.getcwd()

上記の行は、Pythonファイル(この例ではFirstPrediction.py)を含むフォルダへのパスを取得します。

prediction = ImagePrediction() 
prediction.setModelTypeAsResNet() 
prediction.setModelPath(os.path.join(実行パス、 "resnet50_weights_tf_dim_ordering_tf_kernels.h5"))

上記のコードでは、最初の行にImagePrediction()クラスのインスタンスとインスタンスを作成し、次に 2行目の.setModelTypeAsResNet()を呼び出して予測オブジェクトのモデルタイプをResNet に設定し、モデルパスを設定しました。モデルファイルのパス(resnet50_weights_tf_dim_ordering_tf_kernels.h5)に3番目の行のpythonファイルフォルダにコピーします。

predictions、probabilities = prediction.predictImage(os.path.join(実行パス、 "1.jpg")、result_count = 5)

上の行では、画像を予測するために呼び出される関数、つまり.predictImage()関数と等しい2つの変数を定義し、画像へのパスを解析し、予測結果の数を示します。result_count = 5は5つの予測候補を出力します 。predictImage()関数は、2つの返り値がある。

  • predictions : 予測ラベル
  • probabilities : 予測確率

最後にfor文でそれぞれ出力させています。

複数の画像の予測

先ほどのコードでは、1枚の画像に対する予測だけでしたが、次のコードでは、現在のディレクトリにある画像すべての予測が可能です。

from imageai.Prediction import ImagePrediction import os execution_
  path = os.getcwd() 
multiple_prediction = ImagePrediction() multiple_prediction.setModelTypeAsResNet() 
multiple_prediction.setModelPath(os.path.join(execution_path, "resnet50_weights_tf_dim_ordering_tf_kernels.h5")) 
multiple_prediction.loadModel() all_images_array = [] all_files = os.listdir(execution_path) 
for each_file in all_files: 
if(each_file.endswith(".jpg") or each_file.endswith(".png")): 
  all_images_array.append(each_file) 
  results_array = multiple_prediction.predictMultipleImages(all_images_array, result_count_per_image=5) 
  for each_result in results_array: 
    predictions, percentage_probabilities = each_result["predictions"], each_result["percentage_probabilities"] 
  for index in range(len(predictions)): 
    print(predictions[index] , " : " , percentage_probabilities[index])
    print("-----------------------")

toilet_tissue  :  13.990111649036407
-----------------------
jeep  :  6.842944025993347
-----------------------
car_wheel  :  6.719634681940079
-----------------------
seat_belt  :  6.704963743686676
-----------------------
minivan  :  5.861165747046471
-----------------------
bustard  :  52.033573389053345
-----------------------
vulture  :  20.93603014945984
-----------------------
crane  :  10.620493441820145
-----------------------
kite  :  10.205371677875519
-----------------------
white_stork  :  1.6472266986966133
-----------------------
convertible  :  52.45957374572754
-----------------------
sports_car  :  37.612783908843994
-----------------------
pickup  :  3.17511223256588
-----------------------
car_wheel  :  1.8174994736909866
-----------------------
minivan  :  1.7487023025751114
----------------------------------------------

結果がみづらいですね…。今回載せてあるコードをそのまま使っていますので、個々で変えて見てください。

実行速度

ImageAIはすべての画像予測タスクの予測速度を変えられるようです。予測速度を定義すると、20%〜60%の割合で予測時間を短縮できるそうです。利用可能な予測速度は、“normal”(デフォルト)、“fast”  “faster” および “fastest” です。実際に速度を変えるには、以下に示すようにモデルをロードするときに望む速度を記述するだけで可能です。

prediction.loadModel(prediction_speed = "fast")

  • 予測速度:normal 実行速度:2.7891066074371340[sec]
  • 予測速度:fast      実行速度:1.9949402809143066[sec]
  • 予測速度:faster   実行速度:1.5478324890136719[sec]
  • 予測速度:fastest 実行速度:1.4464182853698730[sec]

GoogleColaboratory上で試したのですが、連続で実行するとドンドン速度が落ちていくので、今回の検証では一回一回、ランタイムリセットをかけて計測した。

確かに高速になっているが、実行していて出力される予測結果がかなり変動していた。最初に取り上げた車を例としてすべての速度での予測結果を見てみる。

予測速度: normal

convertible  :  52.45957374572754
-----------------------
sports_car  :  37.612783908843994
-----------------------
pickup  :  3.17511223256588
-----------------------
car_wheel  :  1.8174994736909866
-----------------------
minivan  :  1.7487023025751114
-----------------------

予測速度: fast

sports_car  :  55.51350116729736
-----------------------
pickup  :  19.860127568244934
-----------------------
convertible  :  17.88404732942581
-----------------------
tow_truck  :  2.3575657978653908
-----------------------
car_wheel  :  1.8646074458956718
-----------------------

予測速度: faster

sports_car  :  79.90464568138123
-----------------------
tow_truck  :  9.75109338760376
-----------------------
convertible  :  7.05607682466507
-----------------------
racer  :  1.873583346605301
-----------------------
car_wheel  :  0.7379386108368635
-----------------------

予測速度: fastest

tow_truck  :  62.50318884849548
-----------------------
sports_car  :  31.261593103408813
-----------------------
racer  :  2.213984914124012
-----------------------
fire_engine  :  1.781299151480198
-----------------------
ambulance  :  0.8790277875959873
-----------------------

文には予測精度はあまり変わらないと書いてあったんですがこれはどうなんでしょうか…。でも、精度よりとにかく速度をという場面もあると思うので、時間を調節できるのはいいと思います。

動画の物体認識

最後に、画像ではなく、動画を使ってやって見たいと思います。

これについても、肝心のコードはこれだけです。

from imageai.Detection 
import VideoObjectDetection 
import os execution_path = os.getcwd() 
detector = VideoObjectDetection() 
detector.setModelTypeAsRetinaNet() 
detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5")) 
detector.loadModel() 
video_path = detector.detectObjectsFromVideo(input_file_path= "traffic.mp4",output_file_path="traffic_detected", frames_per_second=20, log_progress=True) 
print(video_path)

CPUだとかなり時間がかかってしまいました。

動画を載せようと思ったのですが、かなり重くなってしまったので、きになる方はこちらに掲載されている動画を見てください。

いかがだったでしょうか。CPUだとやはりリアルタイムには遠いですね。ですが、このコード量でこれが実現できるというのはやはりかなりの利点のように感じました。

最後まで読んでいただきありがとうございました。よろしければこの記事をシェアしていただけると励みになります。よろしくお願いします

スポンサーリンク
レクタングル広告(大)
レクタングル広告(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
レクタングル広告(大)