LoginSignup
0
0

OMRON SENTECカメラをPythonとOpenCVで制御する方法(3)

Posted at

前回記事の続きです。

CMyCallback クラスの詳細解説

CMyCallback クラスは、カメラから取得した画像データを処理し、スレッドセーフな方法で画像データを保持するために設計されています。このクラスは、データストリームからのコールバックを処理するためのコールバック関数を含んでいます。

クラスの構造

class CMyCallback:
    """
    Class that contains a callback function.
    """

このクラスは、コールバック関数を含むクラスであることを示しています。

初期化 (__init__)

    def __init__(self):
        self._image = None
        self._lock = threading.Lock()
  • self._image: 取得した画像データを保持するための変数です。初期値は None に設定されています。
  • self._lock: スレッドセーフなアクセスを保証するためのロックオブジェクトです。これにより、マルチスレッド環境でのデータ競合を防ぎます。

プロパティ (image)

    @property
    def image(self):
        """Property: return PyIStImage of the grabbed image."""
        duplicate = None
        self._lock.acquire()
        if self._image is not None:
            duplicate = self._image.copy()
        self._lock.release()
        return duplicate
  • @property: このデコレータにより、image メソッドをプロパティとしてアクセスできるようになります。
  • self._lock.acquire(): ロックを取得し、他のスレッドが self._image にアクセスするのを防ぎます。
  • self._image.copy(): 画像データのコピーを作成し、オリジナルデータが他のスレッドによって変更されるのを防ぎます。
  • self._lock.release(): ロックを解放し、他のスレッドが self._image にアクセスできるようにします。
  • return duplicate: コピーした画像データを返します。

コールバック関数 (datastream_callback)

    def datastream_callback(self, 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.
        """
  • handle: コールバックをトリガーするハンドル。
  • context: コールバック登録時に渡されたユーザーデータ。
コールバック処理の流れ
  1. データストリームの取得
        st_datastream = handle.module

handle.module を使ってデータストリームオブジェクトを取得します。

  1. バッファの取得
        if st_datastream:
            with st_datastream.retrieve_buffer() as st_buffer:

データストリームからバッファを取得します。with 文を使うことで、バッファの自動解放を保証します。

  1. 画像データの確認と取得
                if st_buffer.info.is_image_present:
                    st_image = st_buffer.get_image()

取得したバッファが画像データを含んでいるか確認し、画像オブジェクトを取得します。

  1. ピクセルフォーマットの確認
                    pixel_format = st_image.pixel_format
                    pixel_format_info = st.get_pixel_format_info(pixel_format)

                    if not(pixel_format_info.is_mono or pixel_format_info.is_bayer):
                        return

ピクセルフォーマットを取得し、それがモノクロまたはベイヤー形式であるかを確認します。それ以外の場合は処理を終了します。

  1. 画像データの取得
                    data = st_image.get_image_data()

画像の生データを取得します。

  1. ピクセル値のスケーリング
                    if pixel_format_info.each_component_total_bit_count > 8:
                        nparr = np.frombuffer(data, np.uint16)
                        division = pow(2, pixel_format_info.each_component_valid_bit_count - 8)
                        nparr = (nparr / division).astype('uint8')
                    else:
                        nparr = np.frombuffer(data, np.uint8)

各ピクセルコンポーネントが8ビットを超える場合、スケーリングを行います。スケーリングしない場合はそのままのデータを使用します。

  1. 画像データの整形
                    nparr = nparr.reshape(st_image.height, st_image.width, 1)

画像データを高さと幅に基づいて再整形します。

  1. ベイヤー変換
                    if pixel_format_info.is_bayer:
                        bayer_type = pixel_format_info.get_pixel_color_filter()
                        if bayer_type == st.EStPixelColorFilter.BayerRG:
                            nparr = cv2.cvtColor(nparr, cv2.COLOR_BAYER_RG2RGB)
                        elif bayer_type == st.EStPixelColorFilter.BayerGR:
                            nparr = cv2.cvtColor(nparr, cv2.COLOR_BAYER_GR2RGB)
                        elif bayer_type == st.EStPixelColorFilter.BayerGB:
                            nparr = cv2.cvtColor(nparr, cv2.COLOR_BAYER_GB2RGB)
                        elif bayer_type == st.EStPixelColorFilter.BayerBG:
                            nparr = cv2.cvtColor(nparr, cv2.COLOR_BAYER_BG2RGB)

ベイヤー形式の画像データをRGB形式に変換します。

  1. 画像データのリサイズと保存
                    nparr = cv2.resize(nparr, None, fx=DISPLAY_RESIZE_FACTOR, fy=DISPLAY_RESIZE_FACTOR)
                    self._lock.acquire()
                    self._image = nparr
                    self._lock.release()

画像データをリサイズし、self._image に保存します。この時、スレッドセーフを保証するためにロックを取得してから画像データを保存し、保存後にロックを解放します。

まとめ

CMyCallback クラスは、カメラから取得した画像データを安全に処理し保存するための重要なクラスです。スレッドセーフな方法で画像データを保持するためにロック機構を使用し、データストリームからのコールバックを適切に処理します。このクラスの設計により、リアルタイムで画像を処理し表示することが可能になります。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0