OMRON SENTECカメラ Python Buildup (6) grab_ip_opencv.py

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

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

### コードの全体説明

このコードは、StApiを使用してカメラから画像データを取得し、そのデータをOpenCVを使って表示するサンプルです。主な機能は以下の通りです：

1. StApiの初期化
2. カメラへの接続
3. 画像データの取得
4. StApi IPを使用したBayer画像形式のBGR8への変換
5. OpenCVを使った画像のプレビュー

### コードの詳細分析

#### インポートと設定

```python
import cv2
import numpy as np
import stapipy as st

# 取得する画像の枚数
number_of_images_to_grab = 1000

# OpenCVを使用して表示する際の画像スケール
DISPLAY_RESIZE_FACTOR = 0.3
```

- `cv2`: OpenCVライブラリをインポートします。
- `numpy`: 画像データの処理に使用するため、NumPyライブラリをインポートします。
- `stapipy`: StApiライブラリをインポートします。

#### メイン部分

```python
try:
    # StApiを初期化
    st.initialize()

    # コンバーターを初期化
    st_converter = st.create_converter(st.EStConverterType.PixelFormat)
    st_converter.destination_pixel_format = \
        st.EStPixelFormatNamingConvention.BGR8

    # デバイスのスキャンと接続のためのシステムオブジェクトを作成
    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()

    # ホスト側の画像取得を開始
    st_datastream.start_acquisition(number_of_images_to_grab)

    # カメラ側の画像取得を開始
    st_device.acquisition_start()

    # データ取得とステータス確認のためのループ
    while st_datastream.is_grabbing:
        # 'with'を使用してローカル変数st_bufferを作成
        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]))

                # 画像を変換し、NumPy配列を取得
                st_image = st_converter.convert(st_image)
                data = st_image.get_image_data()
                nparr = np.frombuffer(data, np.uint8)
                nparr = nparr.reshape(st_image.height, st_image.width, 3)

                # 画像をリサイズして表示
                nparr = cv2.resize(nparr, None,
                                   fx=DISPLAY_RESIZE_FACTOR,
                                   fy=DISPLAY_RESIZE_FACTOR)
                cv2.imshow('image', nparr)
                cv2.waitKey(1)
            else:
                # 取得したデータに画像データが含まれていない場合
                print("Image data does not exist.")

    # カメラ側の画像取得を停止
    st_device.acquisition_stop()

    # ホスト側の画像取得を停止
    st_datastream.stop_acquisition()

except Exception as exception:
    print(exception)
```

### 主な処理の流れ

1. **初期化と接続**:
   - `st.initialize()`でStApiを初期化し、`st.create_system()`でシステムオブジェクトを作成、`st_system.create_first_device()`で最初に検出されたデバイスに接続します。
   - デバイスの名前を表示します。

2. **コンバーターの初期化**:
   - `st.create_converter()`を使用してピクセルフォーマットコンバーターを作成し、`BGR8`に変換するよう設定します。

3. **データストリームの作成と画像取得の開始**:
   - `st_device.create_datastream()`でデータストリームオブジェクトを作成し、`st_datastream.start_acquisition()`で画像取得を開始します。

4. **画像データの取得と処理**:
   - `st_datastream.retrieve_buffer()`でバッファを取得し、`st_buffer.get_image()`で画像データを取得します。
   - `st_converter.convert()`を使用して、取得した画像データをBGR8形式に変換します。
   - NumPy配列に変換し、`cv2.imshow()`で表示します。

5. **画像取得の停止**:
   - `st_device.acquisition_stop()`と`st_datastream.stop_acquisition()`で画像取得を停止します。

### StApi IPを利用する理由とメリット

#### 理由

1. **効率的な画像フォーマット変換**:
   - StApi IPを使用することで、Bayerフォーマットなどの生データを効率的にRGBやBGR形式に変換することができます。これにより、後続の画像処理が簡単になります。

2. **一貫したデータ処理**:
   - StApi IPを使用することで、画像データの取得から変換まで一貫して処理することができ、開発者は画像データの詳細なフォーマット処理を意識する必要がありません。

#### メリット

1. **高パフォーマンス**:
   - StApi IPはハードウェアの最適化を利用しており、高速で効率的な画像フォーマット変換を提供します。

2. **シンプルなインターフェース**:
   - 複雑な画像処理アルゴリズムを簡単に使用できるため、開発者は主要な画像処理タスクに集中できます。

3. **互換性**:
   - StApi IPはさまざまなカメラやセンサーと互換性があり、幅広い用途で使用することができます。

このコードを使用することで、カメラから取得した画像データを効率的に処理し、リアルタイムで表示することができます。



---



## camera 8 bit mono 



上記のコードは、StApi IPを使用していないため、基本的なモノクロ8bit画像の取得と表示のみに焦点を当てています。StApi IPを使用して、画像の処理や変換を行う部分を追加する場合、以下のようにコードを修正します。

### StApi IPを使用するコードの修正

StApi IPを利用するには、特に画像の形式変換や高度な処理にStApi IPの機能を利用します。この場合、モノクロ画像に対しては変換処理がシンプルですが、コンバーターを使用してデータを処理する方法を示します。

#### 修正後のコード

```python
import cv2
import numpy as np
import stapipy as st

# 取得する画像の枚数
number_of_images_to_grab = 100

# OpenCVを使用して表示する際の画像スケール
DISPLAY_RESIZE_FACTOR = 0.3

try:
    # StApiを初期化
    st.initialize()

    # コンバーターを初期化（モノクロ画像用）
    st_converter = st.create_converter(st.EStConverterType.PixelFormat)
    st_converter.destination_pixel_format = st.EStPixelFormatNamingConvention.Mono8

    # デバイスのスキャンと接続のためのシステムオブジェクトを作成
    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()

    # ホスト側の画像取得を開始
    st_datastream.start_acquisition(number_of_images_to_grab)

    # カメラ側の画像取得を開始
    st_device.acquisition_start()

    # データ取得とステータス確認のためのループ
    while st_datastream.is_grabbing:
        # 'with'を使用してローカル変数st_bufferを作成
        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]))

                # StApi IPコンバーターを使用して画像を変換
                st_image = st_converter.convert(st_image)

                # 変換後の画像データを取得
                data = st_image.get_image_data()

                # データをNumPy配列に変換
                nparr = np.frombuffer(data, np.uint8)

                # 画像を表示用に処理
                nparr = nparr.reshape(st_image.height, st_image.width)

                # 画像をリサイズして表示
                nparr = cv2.resize(nparr, None,
                                   fx=DISPLAY_RESIZE_FACTOR,
                                   fy=DISPLAY_RESIZE_FACTOR)
                cv2.imshow('image', nparr)
                cv2.waitKey(1)
            else:
                # 取得したデータに画像データが含まれていない場合
                print("Image data does not exist.")

    # カメラ側の画像取得を停止
    st_device.acquisition_stop()

    # ホスト側の画像取得を停止
    st_datastream.stop_acquisition()

except Exception as exception:
    print(exception)
```

### 主な変更点

1. **コンバーターの初期化**:

   ```python
   # コンバーターを初期化（モノクロ画像用）
   st_converter = st.create_converter(st.EStConverterType.PixelFormat)
   st_converter.destination_pixel_format = st.EStPixelFormatNamingConvention.Mono8
   ```

   - StApi IPのコンバーターを初期化し、目的のピクセルフォーマットを設定します。

2. **画像データの変換**:

   ```python
   # StApi IPコンバーターを使用して画像を変換
   st_image = st_converter.convert(st_image)
   ```

   - 取得した画像データをStApi IPコンバーターを使用して変換します。

### まとめ

この修正により、StApi IPを使用してモノクロ8bit画像のデータを取得し、適切に変換して表示することができます。StApi IPを使用することで、変換処理が最適化され、高速かつ効率的にデータを処理できるようになります。


## 関連資料


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