プログラマーズガイド¶
StApi Python (stapipy)の構造¶
StApiは3つの主な機能(カメラ制御のためのトランスポート層)で構成されていますが、 このstapipyパッケージはトランスポート層(StApi TL)と画像処理(StApi IP)に対してのみPythonバインディングを提供します。
カメラの設定変更や画像データ、イベントデータ等を取得する機能が提供されます。カメラとの通信にはGenTLモジュールが使用されます。 SDK付属のGenTLモジュールはUSB3VisionおよびGigEVisionに対応しています。CoaXPress用取り込みボードメーカー製のGenTLモジュールを使用することで CoaXPressカメラも利用できます。カメラの設定変更にはGenApiが使用されます。画像処理機能やGUI機能が不要であれば、 この機能(下図の水色線枠内)だけを使用してアプリケーションを開発できます。
モジュール |
主な用途 |
---|---|
System |
ctiファイル(GenTL用ライブラリファイル)の情報取得に使用されます。 |
Interface |
インターフェースに関する設定や接続されているカメラの情報取得などに使用されます。 |
Device |
カメラの設定に使用されます。 |
Data Stream |
画像データ等のストリーミングの設定に使用されます。 |
Stream Buffer |
ストリーミングに使用されているバッファの情報取得に使用されます。 |
対応環境¶
StApi Python(stapipy)はPython wheel(.whl)の形で配布します。 このモジュールはStApi(Sentech SDK)のインストールを必要とし、以下のPythonをサポートします。
Python 3.8.x, 3.9.x, 3.10.x 64bit/32bit (Windows OS)
Python 3.8.x, 3.9.x, 3.10.x 64bit (Linux OS)
Python 3.8.x, 3.9.x, 3.10.x ARM64 (Linux OS)
警告
StApi Pythonを使用するためにSentech SDKのインストールが必要になります。Sentech SDKがインストールされていることを確認してください。
stapipyを使用するアプリケーションを実行するには、Sentech SDKが提供する環境変数を設定する必要があります。
StApi (Sentech SDK)のインストール¶
Sentech SDKのドキュメントに参照ください。
stapipyのインストール¶
stapipyをインストールする際、pip コマンドを実行ください。例:
pip install stapipy-1.2.2-xxx-yyy-zzz.whl
xxx-yyyは下記のようなPythonのバージョンとABIです。
cp38-cp38 : Python 3.8.x
cp39-cp39 : Python 3.9.x
cp310-cp310 : Python 3.10.x
zzzは下記のようなPythonのプラットフォームです。
linux_aarch64 : Linux ARM64
linux_x86_64 : Linux 64 bit
win32 : Windows 32 bit
win_amd64 : Windows 64 bit
エラー処理¶
StApiで例外が発生する際、stapipyはその例外を伝播して stapipy.PyStError
を出送します。
画像データの取得までの流れ¶
stapipyをインポート。
import stapipy as st
StApiライブラリの初期化します。
stapipy.initialize()
を呼び出します。StApiライブラリを使い終わった後は
stapipy.terminate()
を呼び出して終了処理を行います。stapipy.terminate()
を呼び出した後ではstapipy関連の関数やインスタンスなどをアクセスしないようにご注意ください。st.initialize()
システム(GenTLモジュール)をオープンし、
stapipy.PyStSystem
を取得します。stapipy.create_system()
を呼び出します。st_system = st.create_system()
デバイス(カメラ)をオープンし、
PyStDevice
のインスタンスを取得します。stapipy.PyStSystem.create_first_device()
を呼び出します。下記のコードは最初見つけたカメラをオープンします。
st_device = st_system.create_first_device()
データストリームをオープンし、
PyStDataStream
のインスタンスを取得します。stapipy.PyStDevice.create_datastream()
を呼び出します。st_datastream = st_device.create_datastream()
ホスト側画像データの取得を開始します。
stapipy.PyStDataStream.start_acquisition()
を呼び出します。下記のコードは100枚画像を取得します。
st_datastream.start_acquisition(100)
カメラ側画像データの出力を開始します。
stapipy.PyStDevice.acquisition_start()
を呼び出します。st_device.acquisition_start()
画像データが入ったバッファ:py:class:stapipy.PyStStreamBuffer の取得と、使用済バッファのキューへの挿入を繰り返し行います。
バッファをキューに戻すには、
stapipy.PyStStreamBuffer
のインスタンスを解放する必要があります。 インスタンスをNone
にするか、stapipy.PyStStreamBuffer.release()
を呼び出すか、 コンテキストマネージャ(with
)を使うことです。下記のコードはコンテキストマネージャを使用したバッファの取得と再キューイングの例を示します。
while st_datastream.is_grabbing: with st_datastream.retrieve_buffer() as st_buffer: if st_buffer.info.is_image_present: st_image = st_buffer.get_image() print("BlockID={0} Size={1} x {2} First Byte={3}".format( st_buffer.info.frame_id, st_image.width, st_image.height, st_image.get_image_data()[0])) else: print("Image data does not exist.")
カメラ側画像データの出力を停止します。
stapipy.PyStDevice.acquisition_stop()
を呼び出します。st_device.acquisition_stop()
ホスト側画像データの取得を停止します。
stapipy.PyStDataStream.stop_acquisition()
を呼び出します。st_datastream.stop_acquisition()
完全なコードは以下の通りです。
1import stapipy as st
2
3st.initialize()
4st_system = st.create_system()
5st_device = st_system.create_first_device()
6st_datastream = st_device.create_datastream()
7st_datastream.start_acquisition(100)
8st_device.acquisition_start()
9while st_datastream.is_grabbing:
10 with st_datastream.retrieve_buffer() as st_buffer:
11 if st_buffer.info.is_image_present:
12 st_image = st_buffer.get_image()
13 print("BlockID={0} Size={1} x {2} First Byte={3}".format(
14 st_buffer.info.frame_id,
15 st_image.width,
16 st_image.height,
17 st_image.get_image_data()[0]))
18 else:
19 print("Image data does not exist.")
20st_device.acquisition_stop()
21st_datastream.stop_acquisition()
GenApiノードのアクセス¶
stapipyには各GenTLモジュールインスタンス(stapipy.PyStSystem
,
stapipy.PyStInterface
, stapipy.PyStDataStream
,
stapipy.PyStStreamBuffer
)に port
プロパティーがあります。
stapipy.PyStDevice
の場合は、ローカルとリモートポートアクセスがあり、 stapipy.PyStDevice.local_port
と stapipy.PyStDevice.remote_port
になります。
ポートクラスの stapipy.PyStPort.nodemap
プロパティーで stapipy.PyNodeMap
のインスタンスを取得し、GenApiのノードマップのアクセスができます。
GenApiのノードマップからGenApiのノードを取得する場合は stapipy.PyNodeMap.get_node()
を呼び出して、stapipy.PyNode
を取得し、GenApiのノードをアクセスできます。
次のコードの6行目と7行目は、リモートデバイスのGenApiノードマップを取得し、「Width」という名前のノードを取得する方法を示します。
1import stapipy as st
2
3st.initialize()
4st_system = st.create_system()
5st_device = st_system.create_first_device()
6st_nodemap_remote = st_device.remote_port.nodemap
7width_node = st_nodemap_remote.get_node("Width")
8print("Width:", width_node.value)
9print("Interface type:", width_node.principal_interface_type)
単純な使い方では、 stapipy.PyNode.value
を使うことで、ノードの特定のインターフェースにアクセスすることなくノード値を直接読み書きすることが可能です。
包括的な使用法のために、ノードの特定のインターフェースにアクセスすることが必要かもしれません。
プロパティー stapipy.PyNode.principal_interface_type
でノードのインタフェースタイプ(stapipy.EGCInterfaceType
)を取得できます。
次の表は、インターフェイスの種類に対応するクラスの一覧を示します。
インタフェースタイプ |
クラス |
---|---|
IInteger |
|
IBoolean |
|
ICommand |
|
IFloat |
|
IString |
|
IRegister |
|
ICategory |
|
IEnumeration |
|
IEnumEntry |
|
IPort |
さまざまなユースケースに対応するために、ノードの指定されたインタフェースにアクセスする方法は2つあります。
stapipy.PyNode
からインターフェース型のクラスインスタンスを作成すること。クラスが正しくなければ、例外
ValueError
が発生します。この方法はコードの可読性を向上させるために推奨されます。
width = st.PyIInteger(width_node) print("Width min:{0}, max:{1}".format(width.min, width.max))
stapipy.PyNode.get()
を呼び出すこと。ノードのインターフェースタイプに応じて、クラスインスタンスの1つが返されます。
この方法を使用すれば、コードを短くできます。
width = width_node.get() print("Width min:{0}, max:{1}".format(width.min, width.max))
取得画像データからNumPy配列を取得する方法¶
Pythonの科学計算および画像処理パッケージには、ほとんどNumPy配列を使用しています。 PyStImageからNumPy配列を取得する簡単な例については、サンプルプログラム grab_opencv.py (画像変換にはOpenCVを利用されます) と grab_ip_opencv.py (画像変換にはStApi IPを利用されます) を参照してください。