スレッド処理と並行処理#
この視覚表現は、Pythonアプリケーションでの画像取得の仕組みを示しています。
- 画像取得は、pylon内のネイティブ(C++)スレッドで実行されます。
- ユーザーのPythonコードは、バッファキューから画像を取得します。
- この分離により、非同期取得が可能になります。
多くのアプリケーションでは、画像取得の速度が処理速度を上回ります:
並行処理を行わない場合:
- バッファがFillでいっぱいになります。
- フレームがドロップされます。
- レイテンシが増加します。
基本的な実行モデル#
シングルスレッドアプローチは、画像取得パイプラインの最もシンプルな形式です。
例:
while camera.IsGrabbing():
with camera.RetrieveResult(5000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
process(image)
これには次のような欠点があります:
- 処理が取得をブロックします。
- CPU使用率が低い
- スケーラビリティが限られている
プロデューサー・コンシューマーパターン(推奨)#
これは、画像取得パイプラインに対するより洗練されたアプローチです。
- プロデューサー:取得スレッドが画像を取得し、キューにプッシュします。
- Consumer: ワーカー スレッドが画像を独立して処理します。
カスタムスレッドを使用した実装例#
情報
InstantCameraが提供するグラブループスレッドを使用できます(grab_using_grab_loop_threadサンプルを参照してください)。これはデモンストレーション目的のみのカスタム実装です。
import threading
import queue
from pypylon import pylon
def process(image):
print(image.shape)
image_queue = queue.Queue(maxsize=10)
# Producer thread
def grab_loop(camera):
while camera.IsGrabbing():
with camera.RetrieveResult(5000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
image_queue.put(image)
# Consumer thread
def process_loop():
while True:
image = image_queue.get()
process(image)
image_queue.task_done()
with pylon.InstantCamera(pylon.FirstFound) as camera:
camera.StartGrabbing()
grab_thread = threading.Thread(target=grab_loop, args=(camera,))
processing_thread = threading.Thread(target=process_loop)
grab_thread.start()
processing_thread.start()
grab_thread.join()
image_queue.join()
キューの動作とバックプレッシャー#
ストラテジー:
- キューサイズを増やす。
- 手動でフレームをドロップする。
- 使用
LatestImageOnly.
Grab Strategyとの組み合わせ#
LatestImageOnly:未処理の蓄積を軽減します。OneByOne:完全性を確保します。
ベストプラクティス:
スレッドセーフティに関する考慮事項#
- ロックなしでミュータブルなデータを共有しないようにします。
- 他のスレッドに画像を渡す前にコピーします。たとえば、
Array関数と直接組み合わせて使用できます。 - 使用
queue.Queueを使用して安全な通信を行います。
CPU使用率#
並列処理には以下の利点があります:
- CPU使用率の向上
- 関心の分離
- スケーラブルなアーキテクチャ
マルチスレッドを使用するタイミング#
次のような状況ではスレッドを使用します:
- 処理速度が取り込み速度よりも遅い。
- 複数の処理ステージが存在する。
- リアルタイムの応答性が求められる。
次のような状況ではスレッドを使用しないようにします:
- 処理負荷がごくわずかである。
- システム記述は最小限に抑える必要があります。
高度なパターン(概要)#
マルチステージパイプライン#
多段階のパイプラインにより、画像処理が並行して実行されキューを介してデータを交換する独立したステップに分割されます。
マルチコンシューマー構成#
概念的なパイプライン#
主なポイント#
- 取り込みと処理は分離する必要があります。
- 拡張性のためにプロデューサー・コンシューマー・パターンを使用します。
- キューにより、スレッドセーフな通信が提供されます。
- スレッド化によりパフォーマンスは向上しますが、複雑さが増します。