OMRON SENTECカメラ Python Buildup (2) grab_callback.py

こちらの資料を読んでください。

https://qiita.com/kotai2003/items/19d840553fc6d69ec17d

### コード全体の説明

このコードは、カメラからの画像データを取得するためのコールバック関数を使用する方法を示すサンプルです。具体的には、以下の手順を実行します：

1. StApiの初期化
2. カメラへの接続
3. コールバック関数の登録と使用
4. コールバック関数を通じた画像データの取得

### コード

```python
"""
 This sample shows how to use callback function to acquire image data from camera.
 The following points will be demonstrated in this sample code:
 - Initialize StApi
 - Connect to camera
 - Register and use callback function with StApi
 - Acquire image data via callback function
"""

import stapipy as st



def datastream_callback(handle=None, context=None):
    """
    Callback to handle events from DataStream.

    :param handle: handle that trigger the callback.
    :param context: user data passed on during callback registration.
    """
    st_datastream = handle.module
    if st_datastream:
        with st_datastream.retrieve_buffer() as st_buffer:
            # Check if the acquired data contains image data.
            if st_buffer.info.is_image_present:
                # Create an image object.
                st_image = st_buffer.get_image()
                # Display the information of the acquired image data.
                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:
                # If the acquired data contains no image data.
                print("Image data does not exist.")


if __name__ == "__main__":
    try:
        # Initialize StApi before using.
        st.initialize()

        # Create a system object for device scan and connection.
        st_system = st.create_system()

        # Connect to first detected device.
        st_device = st_system.create_first_device()

        # Display DisplayName of the device.
        print('Device=', st_device.info.display_name)

        # Create a datastream object for handling image stream data.
        st_datastream = st_device.create_datastream()

        # Register callback for datastream
        callback = st_datastream.register_callback(datastream_callback)

        # Start the image acquisition of the host (local machine) side.
        st_datastream.start_acquisition()

        # Start the image acquisition of the camera side.
        st_device.acquisition_start()

        # Press enter to terminate.
        input("Press enter to terminate")

        # Stop the image acquisition of the camera side
        st_device.acquisition_stop()

        # Stop the image acquisition of the host side
        st_datastream.stop_acquisition()

    except Exception as exception:
        print(exception)

```


### コードの詳細分析

#### インポートとコールバック関数の定義

```python
import stapipy as st

def datastream_callback(handle=None, context=None):
    st_datastream = handle.module
    if st_datastream:
        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`ライブラリをインポートし、コールバック関数`datastream_callback`を定義しています。この関数は、データストリームのイベントを処理し、画像データが存在する場合、その情報を表示します。

#### メイン部分

```python
if __name__ == "__main__":
    try:
        st.initialize()
        st_system = st.create_system()
        st_device = st_system.create_first_device()
        print('Device=', st_device.info.display_name)
        st_datastream = st_device.create_datastream()
        callback = st_datastream.register_callback(datastream_callback)
        st_datastream.start_acquisition()
        st_device.acquisition_start()
        input("Press enter to terminate")
        st_device.acquisition_stop()
        st_datastream.stop_acquisition()
    except Exception as exception:
        print(exception)
```

1. **初期化**: `st.initialize()`でStApiを初期化します。
2. **デバイスの作成**: `st.create_system()`でシステムオブジェクトを作成し、`st_system.create_first_device()`で最初に検出されたデバイスに接続します。
3. **デバイス情報の表示**: 接続したデバイスの表示名を表示します。
4. **データストリームの作成**: データストリームオブジェクトを作成し、コールバック関数を登録します。
5. **画像取得の開始**: デバイスとホストの両方で画像取得を開始します。
6. **終了待ち**: ユーザーがEnterキーを押すまで待機します。
7. **画像取得の停止**: デバイスとホストの両方で画像取得を停止します。

### まとめ

このコードは、カメラからの画像データを効率的に取得するためにコールバック関数を利用する方法を示しています。主なポイントは、StApiの初期化、デバイス接続、コールバック関数の登録と使用、そして画像取得の開始と停止です。コールバック関数を使用することで、画像データの取得と処理を非同期的に実行できます。



### 2つのプログラムの比較

#### `grab.py` の要点

- メインスレッド内でループを用いて画像データを取得。
- 同期的なデータ取得。
- 指定した数の画像 (`number_of_images_to_grab = 100`) を取得するまでループを継続。
- https://qiita.com/kotai2003/items/a20f4ee0ba978e54808e

#### `grab_callback.py` の要点

- コールバック関数を使用して画像データを取得。
- 非同期的なデータ取得。
- コールバック関数が呼び出されるたびに画像データを処理。



## 関連資料


https://qiita.com/kotai2003/items/a20f4ee0ba978e54808e

https://qiita.com/kotai2003/items/c35196f62c8d8eb8a28a

https://qiita.com/kotai2003/items/23a0d0546b0e76a12fff

https://qiita.com/kotai2003/items/a1c9a12baac8311a8790

https://qiita.com/kotai2003/items/f273973df27004ff32a1

https://qiita.com/kotai2003/items/2ac6ae2a6400edcca4b0

https://qiita.com/kotai2003/items/68e9d70fb1270855b16f

https://qiita.com/kotai2003/items/5aa5bc90ddcf8b1f5362