原文:OpenCV Computer Vision with Python
ライセンス: CC BY-NC-SA 4.0
翻訳者:フライング ドラゴン
この記事は[ApacheCN Computer Vision Translation Collection]からのものであり、翻訳後編集 (MTPE)プロセスを使用して、可能な限り効率を向上させています。
他人があなたに利益がないと言うなら、しないほうがいいですし、他人があなたが何かをやったと言えば、本当にやったほうがいいのです。
付録 A: Pygame との統合
この付録では、OpenCV アプリケーションで Pygame ライブラリをセットアップする方法と、ウィンドウ管理に Pygame を使用する方法を示します。さらに、付録では、Pygame の他の機能の概要と、Pygame を学習するためのいくつかのリソースが提供されます。
知らせ
この章の完成したコードはすべて、私の Web サイトからダウンロードできます。
Pygame をインストールする
第 1 章「OpenCV のセットアップ」で説明した方法の 1 つに従って、Python をすでにセットアップしていると仮定します。既存のセットアップに応じて、次のいずれかの方法で Pygame をインストールできます。
-
32 ビット Python を搭載した Windows:次の場所からPygame 1.9.1 をダウンロードしてインストールします。
-
64 ビット Python を搭載した Windows:次の場所からPygame 1.9.2 プレビューをダウンロードしてインストールします。
-
Macports を備えた Mac: ターミナルを開き、次のコマンドを実行します。
$ sudo port install py27-game
-
Homebrew を搭載した Mac: ターミナルを開き、次のコマンドを実行して Pygame の依存関係をインストールし、Pygame 自体をインストールします。
$ brew install sdl sdl_image sdl_mixer sdl_ttf smpeg portmidi $ /usr/local/share/python/pip install \ > hg+http://bitbucket.org/pygame/pygame
-
Ubuntu とその派生製品: ターミナルを開き、次のコマンドを実行します。
$ sudo apt-get install python-pygame
-
その他の Unix 系システム: Pygame は、多くのシステムの標準リポジトリで利用できます。一般的なパッケージ名には、、、、、および
pygame
が含まれpygame27
ます。py-game
py27-game
python-pygame,
python27-pygame
これで、Pygame を使用できるようになりました。
ドキュメントとチュートリアル
Pygame の API ドキュメントといくつかのチュートリアルは、オンラインで次の場所にあります。
Al Sweigart の『Making Games with Python and Pygame』は、いくつかの古典的なゲームを Pygame 1.9.1 で再作成するためのクックブックです。無料の電子コピーは、次の Web サイトからオンラインで入手できます。または、以下のWebサイトからPDFファイルをダウンロードしてください。
派生Manager.WindowManager
第 2 章「カメラ、ファイル、および GUI の処理」で説明したように、オブジェクト指向設計により、OpenCV の HighGUI ウィンドウ マネージャーを Pygame などの別のウィンドウ マネージャーに簡単に切り替えることができます。これを行うには、クラスをサブクラス化し、 、、のmanagers.WindowManager
4 つのメソッドをオーバーライドするだけです。また、いくつかの新しい依存関係をインポートする必要があります。createWindow()
show()
destroyWindow()
processEvents()
managers.py
続行するには、第 2 章「カメラ、ファイル、および GUI の操作」のファイルと、第 4 章「Haar カスケードによる顔の追跡」のファイルが必要ですutils.py
。ではutils.py
、必要な関数は 1 つだけですisGray()
。これは、第 4 章「Haar カスケードを使用した顔追跡」で実装します。managers.py
次のインポートを追加するように編集してみましょう。
import pygame
import utils
また、 ではmanagers.py
、実行後のどこかに、次の名前の新しいサブクラスWindowManager
を追加します。PygameWindowManager
class PygameWindowManager(WindowManager):
def createWindow(self):
pygame.display.init()
pygame.display.set_caption(self._windowName)
self._isWindowCreated = True
def show(self, frame):
# Find the frame's dimensions in (w, h) format.
frameSize = frame.shape[1::-1]
# Convert the frame to RGB, which Pygame requires.
if utils.isGray(frame):
conversionType = cv2.COLOR_GRAY2RGB
else:
conversionType = cv2.COLOR_BGR2RGB
rgbFrame = cv2.cvtColor(frame, conversionType)
# Convert the frame to Pygame's Surface type.
pygameFrame = pygame.image.frombuffer(
rgbFrame.tostring(), frameSize, 'RGB')
# Resize the window to match the frame.
displaySurface = pygame.display.set_mode(frameSize)
# Blit and display the frame.
displaySurface.blit(pygameFrame, (0, 0))
pygame.display.flip()
def destroyWindow(self):
pygame.display.quit()
self._isWindowCreated = False
def processEvents(self):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and \
self.keypressCallback is not None:
self.keypressCallback(event.key)
elif event.type == pygame.QUIT:
self.destroyWindow()
return
pygame.display
と の2 つの Pygame モジュールを使用していることに注意してくださいpygame.event
。
pygame.display.init()
ウィンドウを作成するには呼び出し、pygame.display.quit()
ウィンドウを破棄するには呼び出します。display.init()
Pygame はシングル ウィンドウ アプリケーションでのみ動作するため、呼び出しを繰り返しても効果はありません。Pygame ウィンドウの描画面のタイプは ですpygame.Surface
。Surface
それへの参照を取得するには、pygame.display.get_surface()
または を呼び出すことができますpygame.display.set_mode()
。後者の関数は、エンティティを返す前にエンティティの属性を変更しますSurface
。1 つのSurface
エンティティには、パラメータとして別のエンティティと、後者を最初のエンティティ上に「白くする」(ペイントする) 必要がある座標ペアblit()
を取るメソッドがあります。現在のフレームのウィンドウの更新が完了したら、それを呼び出して表示する必要があります。Surface
Surface
Surface
pygame.display.flip()
などのイベントは、を呼び出すことでpygame.event.get()
ポーリングできkeypresses
、最後の呼び出し以降に発生したすべてのイベントのリストが返されます。各イベントは type で、キーの押下pygame.event.Event
などのイベントのカテゴリを示す属性 type と、ウィンドウの閉じるボタンがクリックされたことを示す pygame.QUIT を持ちます。の値に応じて、エンティティはイベント(ASCII キー コード) などの他のプロパティを持つ場合があります。pygame.KEYDOWN
type
Event
KEYDOWN
key
HighGUI の基本を使用するのとは対照的に、フレームごとに OpenCV の画像形式と Pygame の形式の間で変換を行うことによりWindowManager
、ある程度のオーバーヘッドが発生します。ただし、通常のウィンドウを閉じる動作は提供されますが、base には提供されません。PygameWindowManager
Surface
PygameWindowManager
WindowManager
アプリケーションを変更する
の代わりにcameo.py
使用するようにファイルを変更しましょう。で次の行を見つけます。PygameWindowManager
WindowManager
cameo.py
from managers import WindowManager, CaptureManager
これを次のように置き換えます。
from managers import PygameWindowManager as WindowManager, \
CaptureManager
それで全部です!Pygame ウィンドウではcameo.py
、標準の「閉じる」ボタンをクリックするとウィンドウが閉じるはずです。
Pygame のさらなる使用
pygame.display
およびモジュールpygame.event
のいくつかの基本的な機能のみを使用しました。Pygame はさらに多くの機能を提供します。
- 2D ジオメトリを描画する
- テキストを描画する
- 描画可能な AI エンティティ (スプライト) のグループ化を管理する
- Windows、キーボード、マウス、ジョイスティック/ゲームパッドに関連するさまざまな入力イベントをキャプチャします。
- カスタムイベントを作成する
- サウンドと音楽の再生と合成
たとえば、Pygame はコンピューター ビジョンを使用するゲームに適したバックエンドである可能性がありますが、HighGUI は適していません。
要約する
これまでに、Pygame を使用して画像を表示しイベントをキャプチャしながら、OpenCV を使用して画像をキャプチャ (場合によっては操作) するアプリケーションが完成しているはずです。この基本的な統合例から始めて、他の Pygame 機能をラップするように拡張したりPygameWindowManager
、別のWindowManager
ライブラリをラップするために別のサブクラスを作成したりすることもできます。
付録 B: カスタム ターゲットの Haar カスケードの生成
この付録では、第 4 章「Haar カスケードを使用した顔の追跡」で使用したような Haar カスケード XML ファイルを生成する方法を説明します。独自のカスケード ファイルを生成することで、顔だけでなくあらゆるパターンやオブジェクトを追跡できる可能性があります。ただし、良い結果はすぐには得られないかもしれません。画像を慎重に収集し、スクリプトのパラメータを設定し、実際のテストを実行して反復する必要がありました。多大な労力と処理時間がかかる場合があります。
ポジティブなトレーニング画像とネガティブなトレーニング画像を収集する
フラッシュカードという教え方をご存知ですか?ここでは、幼児に言葉と認識スキルを教える方法を紹介します。教師はクラスに一連の写真を見せ、次のように言いました。
「牛だよ、もー!馬だよ、ねえ!」
カスケード ファイルは、フラッシュカードの教育法と同様の方法で生成されます。牛を認識する方法を学習するには、コンピューターが牛として事前に識別されたポジティブなトレーニング画像と、 「牛ではない」として事前に識別されたネガティブなトレーニング画像が必要です。トレーナーとしての私たちの最初のステップは、これら 2 セットの画像を収集することです。
使用するポジティブなトレーニング画像の数を決定するときは、ユーザーがオブジェクトを見るさまざまな方法を考慮する必要があります。理想的には、最も単純なケースは、ターゲットが常に平面上にある 2D パターンである場合です。この場合、単一のポジティブトレーニング画像で十分である可能性があります。ただし、場合によっては、数百または数千のトレーニング画像が必要になる場合もあります。ターゲットがあなたの国の旗だとしましょう。文書に印刷する場合、ロゴの外観は予測可能ですが、風に吹かれる布地に印刷する場合、ロゴの外観は大きく異なる可能性があります。人間の顔などの自然な 3D オブジェクトには、より広範囲の外観が含まれる場合があります。理想的には、正面トレーニング画像のセットは、カメラが捉える可能性のある多くのバリエーションを表す必要があります。オプションで、正面トレーニング画像にはオブジェクトの複数のインスタンスを含めることができます。
ネガティブ トレーニング セットでは、オブジェクトのインスタンスは含まれていないが、カメラがキャプチャする可能性のある他のものは含まれている多数の画像が必要です。たとえば、旗がターゲットの場合、ネガティブ トレーニング セットには、さまざまな気象条件での空の写真が含まれる可能性があります。(空は旗ではありませんが、その背後によく見られます。) ただし、過度に思い込みすぎないでください。カメラの環境が予測不可能で、オブジェクトがさまざまな設定で表示される場合は、さまざまなネガティブ トレーニング イメージを使用します。複数のトレーニング シナリオで再利用できる環境イメージの共通セットを構築することを検討してください。、
トレーニングの実行可能ファイルを見つける
カスケード トレーニングをできるだけ自動化するために、OpenCV は 2 つの実行可能ファイルを提供します。これらの名前と場所は、次の 2 つのセクションで説明するように、オペレーティング システムと OpenCV 固有の設定によって異なります。
窓上
ONopencv_createsamples.exe
Windows 上の 2 つの実行可能ファイルは、と と呼ばれますONopencv_traincascade.exe
。これらは事前に構築されたものではありません。代わりに、ソースから OpenCV をコンパイルした場合にのみ存在します。第 1 章「OpenCV の設定」で選択したコンパイル方法に応じて、親フォルダーは次のフォルダーのいずれかになります。
- ミンGW:
<unzip_destination>\bin
- Visual Studio または Visual C++ Express:
<unzip_destination>\bin\Release
実行可能ファイルのフォルダーをシステムPath
変数に追加する場合は、第 1 章「OpenCV のセットアップ」の「Windows XP、Windows Vista、Windows 7 および Windows 8 での選択」セクションの情報ボックスを参照してください。それ以外の場合は、実行可能ファイルを実行するときに必要になるため、実行可能ファイルへのフルパスをメモしておきます。
Mac、Ubuntu、およびその他の Unix 系システムの場合
Mac、Ubuntu、およびその他の Unix 系システム上の 2 つの実行可能ファイルは、opencv_createsamples
および と呼ばれますopencv_traincascade
。親フォルダーは、システムと第 1 章「OpenCV のセットアップ」で選択した方法に応じて、次のフォルダーのいずれかになります。
- MacPorts を搭載した Mac:
/opt/local/bin
- Homebrew を搭載した Mac:
/opt/local/bin
または/opt/local/sbin
- Apt を使用した Ubuntu:
/usr/bin
- 私のカスタム インストール スクリプトを使用した Ubuntu:
/usr/local/bin
- その他の Unix 系システム:
/usr/bin
および/usr/local/bin
Homebrew を搭載した Mac を除き、デフォルトでは、実行可能ファイルのフォルダーは にあるはずですPATH
。Homebrew の場合、関連するフォルダーを追加する場合はPATH
、第 1 章「OpenCV のセットアップ」の「既製パッケージでの Homebrew の使用 (深度カメラのサポートなし)」の 2 番目の部分の手順を参照してください。それ以外の場合は、実行可能ファイルを実行するときに必要になるため、実行可能ファイルへのフルパスをメモしておきます。
トレーニングセットを作成してカスケードする
<opencv_createsamples>
以降、これら 2 つの実行可能ファイルを およびと呼びます<opencv_traincascade>
。ご使用のシステムとセットアップに適切なパスとファイル名を忘れずに置き換えてください。
これらの実行可能ファイルには、入力および出力として特定のデータ ファイルがあります。これらのデータ ファイルを生成する一般的な方法は次のとおりです。
- 一連のネガティブ トレーニング イメージを説明するテキスト ファイルを手動で作成します。このファイルを と呼びます
<negative_description>
。 - 一連の正面トレーニング画像を説明するテキスト ファイルを手動で作成します。このファイルを と呼びます
<positive_description>
。 <negative_description>
と を引数として<positive_description>
実行します<opencv_createsamples>
。この実行可能ファイルは、トレーニング データを記述するバイナリ ファイルを作成します。後者のファイルを と呼びます<binary_description>
。- 引数
<binary_description>
として実行します<opencv_traincascade>
。この実行可能ファイルは、 と呼ぶバイナリ連結ファイルを作成します<cascade>
。
<negative_description>
、<positive_description>
、<binary_description>
の<cascade>
実際の名前とパスを選択できます。
それでは、3 つのステップを詳しく理解してみましょう。
作成<negative_description>
<negative_description>
すべてのネガティブ トレーニング イメージへの相対パスをリストしたテキスト ファイルです。パスは改行で区切る必要があります。たとえば、次のディレクトリ構造があるとし<negative_description>
ますnegative/desc.txt
。
negative
desc.txt
images
negative 0.png
negative 1.png
その場合、negative/desc.txt
内容は次のようになります。
"images/negative 0.png"
"images/negative 1.png"
画像の数が少ない場合は、そのようなファイルを手動で書き込むことができます。多数の画像の場合は、代わりにコマンド ラインを使用して、特定のパターンに一致する相対パスを検索し、それらの一致をファイルに出力する必要があります。例を続けると、Windows コマンド プロンプトで次のコマンドを実行して生成できますnegative/desc.txt
。
> cd negative
> forfiles /m images\*.png /c "cmd /c echo @relpath" > desc.txt
この場合、相対パスは の形式であることに注意してください.\images\negative 0.png
。これは許容されます。
あるいは、Mac や Ubuntu のターミナルなどの Unix のようなシェルで、次のコマンドを実行できます。
$ cd negative
$ find images/*.png | sed -e "s/^/\"/g;s/$/\"/g" > desc.txt
作成<positive_description>
複数の正面トレーニング画像がある場合に使用する必要があります<positive_description>
。それ以外の場合は、次のセクションに進みます。<positive_description>
すべてのアクティブなトレーニング画像への相対パスをリストしたテキスト ファイルです。各パスの後には、<positive_description>
画像内で見つかったオブジェクト インスタンスの数と、それらのオブジェクト インスタンスが含まれるサブ四角形を示す一連の数字も含まれます。各サブ長方形の数値は、x、y、幅、高さの順序になります。次の例を考えてみましょう。
"images/positive 0.png" 1 120 160 40 40
"images/positive 1.png" 2 200 120 40 60 80 60 20 20
ここで、 には、images/positive 0.png
左上隅(120, 160)
と右下隅を持つサブ四角形内にターゲットのインスタンスが含まれています(160, 200)
。また、images/positive 1.png
ターゲットの 2 つのインスタンスも含めます。インスタンスは、左上隅が(200, 120)
、右下隅が であるサブ長方形内にあります(240, 180)
。もう 1 つのインスタンスは、左上隅(80, 60)
と右下隅を持つ部分長方形内にあります(100, 80)
。
このようなファイルを作成するには、<negative_description>
と同じ方法で画像パスのリストの生成を開始できます。その後、専門家による (人間による) 画像分析に基づいて、ターゲット インスタンスに関するデータを手動で追加する必要がありました。
実行して<opencv_createsamples>
作成<binary_description>
したがって、複数の正面トレーニング画像があると仮定して、 を作成しました<positive_description>
。これは、以下を実行することで生成できます<binary_description>
。
$ <opencv_createsamples> -vec <binary_description> -info <positive_description> -bg <negative_description>
また、ポジティブなトレーニング イメージ ( と呼ぶことにします) がある場合は<positive_image>
、代わりに次のコマンドを実行する必要があります。
$ <opencv_createsamples> -vec <binary_description> -image <positive_image> -bg <negative_description>
他の<opencv_createsamples>
フラグ (オプション) については、公式ドキュメントを参照してください。
実行して<opencv_traincascade>
作成<cascade>
最後に、次を実行して生成できます<cascade>
。
$ <opencv_traincascade> -data <cascade> -vec <binary_description> -bg <negative_description>
<opencv_traincascade>
他の (オプションの) フラグについては、公式ドキュメントを参照してください。
ヒント
声を出す
幸運を祈るために、<opencv_traincascade>
実行時にあざける音を鳴らしてください。たとえば、ポジティブなトレーニング画像が牛の場合は、「モー!」と言います。
テストして改善する<cascade>
<cascade>
CascadeClassifier
は、OpenCV のクラス コンストラクターと互換性のある XML ファイルです。CascadeClassifier
使用方法の例については、FaceTracker
第 4 章「Haar カスケードを使用した顔追跡」の実装を参照してください。。と をコピーして変更するとFaceTracker
、Cameo
追跡されたカスタム ターゲット インスタンスの周囲に四角形を描画する単純なテスト アプリを作成できるはずです。
おそらく、初めてカスケード トレーニングを試すときは、信頼できる追跡結果が得られないでしょう。トレーニングのパフォーマンスを向上させるには、次の手順を実行します。
- 分類の問題をより具体的にすることを検討してください。たとえば、カスケードは
bald, shaven, male face without glasses
単純なカスケードよりもface
トレーニングが簡単な場合があります。その後、結果が改善されたら、問題の範囲を再度拡大してみることができます。 - トレーニング画像をもっと集めて、もっと集めましょう!
- 必ずネガティブなトレーニング画像をすべて
<negative_description>
含め、ネガティブなトレーニング画像のみを含めてください。 - ポジティブなトレーニング画像をすべて含め、ポジティブなトレーニング画像のみ
<positive_description>
を含めるようにしてください。 <positive_description>
で指定された部分四角形が正しいことを確認してください。<opencv_createsamples>
および を使用して<opencv_traincascade>
オプションのフラグを確認して試してください。これらのフラグについては、このページの公式ドキュメントで説明されています。
画像を見つけて頑張ってください!
要約する
CascadeClassifier
OpenCV 互換の連結ファイルを生成するために使用されるデータと実行可能ファイルについて説明しました。これで、お気に入りのものの画像を収集し、それらの分類器をトレーニングできるようになりました。