九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、このブログではこれまで私が経験してきた内容を多く公開しているのですが、スキルアップのためにあまり経験がない分野も取り扱うようにしています。
そして、今回はその中からある事にチャレンジしてみました。
その内容は・・・
写真の中から特定の物体を探し出す「物体検出」
です。
「物体検出」というとちょっと難しく聞こえますが、簡単に言うと、
この写真に「アレ」写ってる❓❓
ということです。
もちろん「アレ」は何でもOKで、例えば以下のようなものがあります。
- 犬
- ビールジョッキ
- 会社のロゴ
などなど。
ということで、今回は私が好きな「ビール🍺」を例にして機械学習を実装する方法をご紹介します。
ぜひ皆さんのお役に立てると嬉しいです😊✨(最後に今回に開発したソースコードと機械学習に必要な画像をダウンロードできます)
開発環境: Python 2.7
目次
やりたいこと
いくつか用意した写真の中から、ビールジョッキが写っているかを調べます。
そして、もし発見したらビールジョッキの部分を切り抜いて「lets-drink-*.jpg」というファイル名で保存します。
では、実際にやっていきましょう!
物体検出する手順
物体検出をするには、機械学習を使います。
そのため、今回の手順は次のようになります。
- ビールジョッキが写っている写真を用意する
- その写真のどこにビールジョッキがあるかを指定する
- 機械学習して「学習データ」をつくる
そして、この「学習データ」を使って(全く別の)写真の中にビールジョッキが写っているかをチェックします。
必要なパッケージをインストールする
まず、今回の機能で必要なパッケージをインストールしておきます。
pip install dlib
pip install opencv-python
※もしCMake must be installed to build the following extensions: dlib
というエラーが出た場合cmake
をインストールしてから実行してください。
機械学習する
では、機械学習でビールジョッキを検出する「学習データ」をつくっていきます。
写真を用意する
はじめに、学習させる写真を用意して、/images/train
フォルダに設置します。
さすがに1枚だけでは機械学習させるには少なすぎますので、最低でも5〜10枚程度は用意した方がいいでしょう。
ただし、ここは機械学習の難しいところですが、数が多ければいいというものではなく、似てる写真ばかりだと学習が偏ってしまい「これしかダメ!」というように「頑固なデータ」になってしまうことがあります。
そのため、適度な数、適度なデータを用意することが重要になります。
もし学習するデータが揃っていない場合はダウンロードするからビールジョッキの画像もダウンロードできますので、そちらを使ってください。
どこに目的の物体があるかが分かるデータをつくる
いろいろと方法があるのですが、今回はインストール不要で機械学習に必要なxml
をつくることができるImgLabというサイトを使わせていただきます。(感謝😊✨)
まずこのサイトにアクセスすると、ポップアップ表示されるので、「UUM! MAY BE NEXT TIME.」ボタンをクリックします。(募金してくれ、というのを断っています😅)
すると、ページ左下に画像を選択するアイコンが表示されるので、ここをクリック。
ファイルを選択するダイアログが表示されるので、/images/train
に用意した全ての写真を選択。
すると、以下のように選択した画像がページ下部に表示されます。(サムネイルをクリックすると画像を拡大表示できます)
次に、選択した写真の「どこにビールジョッキが映っているか?」を指定していきましょう。
まずページ左にある「Rectangle」をクリックしてドラッグ・アンド・ドロップで範囲指定します。(なお、画像が大きすぎる場合はズームで小さくしてください)
全ての画像の範囲指定が完了したら、ページ左上にあるハンバーガーボタンから「Save」を選択。
すると、次のようなポップアップが出るので「Dlib XML」をクリック。
次にファイル名を「beer.xml」にして「SAVE」をクリックします。(もちろん、ファイル名は何でもOKです)
すると、「beer.xml」がダウンロードされるので、/images/train
ファルダに設置しておいてください。
学習用のプログラムをつくる
続いて、実際に機械学習をするためのPython
コードをつくります。
といっても、コード自体はとても簡単ですので以下をコピペしてください。
/train.py
import dlib if __name__ == "__main__": train_xml = "./images/train/beer.xml" svm_file = "beer.svm" options = dlib.simple_object_detector_training_options() dlib.train_simple_object_detector(train_xml, svm_file, options)
機械学習を実行する
では、train.py
を実行して機械学習をしましょう!
以下のコマンドを実行してください。
python train.py
実行が完了すると、beer.svm
という学習データが作成されます。
物体検出する
では、学習データをつくったので、ここからは実際に物体検出をしてみましょう。
写真を用意する
今回はビールジョッキの学習データなので、正解の写真を2枚だけ用意して/images/detection
に設置します。
物体検出するコードをつくる
続いて、Python
コードです。
こちらもコピペでOKです。
/detection.py
import dlib import cv2 import sys import glob import os if __name__ == "__main__": detector = dlib.simple_object_detector('beer.svm') files = glob.glob('images/detection/*.jpg') loop = 1 for file in files: print('[Detecting]: '+ file) img = cv2.imread(file) rectangles = detector(img) for rect in rectangles: print('Found beer!') print(rect); x = rect.left() y = rect.top() w = rect.width() h = rect.height() cv2.imwrite('lets-drink-'+ str(loop) +'.jpg', img[y:y+h, x:x+w]); loop += 1
内容としては、「写真の中にビールジョッキがあるか?」をチェックし、もし存在していたらその座標部分を切り出して保存しています。
なお、ビールが写真が見つかったら「Found beer!」と表示されます😊✨
テストしてみる
では、実際にdetection.py
を実行して確認してみましょう!
python detection.py
すると、以下のような表示になりました。(2つとも検出できました)
[Detecting]: images/detection/akashiyaki.jpg [Detecting]: images/detection/sunflower_seeds.jpg [Detecting]: images/detection/beer_1.jpg Found beer! [(56, 56) (627, 841)] [Detecting]: images/detection/beer_2.jpg Found beer! [(206, 206) (2251, 3018)] [Detecting]: images/detection/hamburger.jpg [Detecting]: images/detection/bechstein_piano.jpg
そして、検出したビールジョッキが切り出されてこのようにファイルが作成されています。
うまくいきました😊✨
ダウンロードする
今回実際に開発したソースコード一式を以下からダウンロードすることができます。(画像も全て入っています)
【Python】ビールジョッキ検出おわりに
ということで、今回は機械学習でビールジョッキを検出するプログラムをご紹介しました。
冒頭でも書きましたが、ビールジョッキに限らずあなたが好きな物体で試すことができます。
過去には、ある会社の商品画像にロゴが入っているものと入っていないものが共存しているので、機械学習で入っていないものだけ探し出すという記事を読んだことがあります。
「なるほど、そういう使い方もあるのか!」
と関心したのですが、AIや機械学習といっても結局は人間の工夫が大事だということだと思います。
ぜひ皆さんも面白いアイデアに応用してみてくださいね。
ではでは〜!