0
0

OMRON SENTECカメラ Python Buildup (5) grab_callback_opencv.py

Last updated at Posted at 2024-05-24

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

コードの全体説明

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

  1. StApiの初期化
  2. カメラへの接続
  3. コールバック関数を用いた画像データの取得
  4. 取得した画像データをOpenCVで処理し表示

クラス CMyCallback の定義とメソッド

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

    def __init__(self):
        self._image = None
        self._lock = threading.Lock()

    @property
    def image(self):
        duplicate = None
        self._lock.acquire()
        if self._image is not None:
            duplicate = self._image.copy()
        self._lock.release()
        return duplicate

    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.
        """
        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()

                    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

                    data = st_image.get_image_data()

                    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)

                    nparr = nparr.reshape(st_image.height, st_image.width, 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)

                    nparr = cv2.resize(nparr, None, fx=DISPLAY_RESIZE_FACTOR, fy=DISPLAY_RESIZE_FACTOR)
                    self._lock.acquire()
                    self._image = nparr
                    self._lock.release()

クラス CMyCallback

  • このクラスは、画像データを取得して処理するためのコールバック関数を含みます。
  • 属性とメソッド:
    • __init__: インスタンス変数 _image とスレッドロック _lock を初期化します。
    • image: スレッドセーフに _image のコピーを返すプロパティ。
    • datastream_callback: 画像データを取得して処理するコールバック関数。

メイン部分

if __name__ == "__main__":
    my_callback = CMyCallback()
    cb_func = my_callback.datastream_callback
    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(cb_func)

        st_datastream.start_acquisition()
        st_device.acquisition_start()

        print("To terminate, focus on the OpenCV window and press any key.")
        while True:
            output_image = my_callback.image
            if output_image is not None:
                cv2.imshow('image', output_image)
            key_input = cv2.waitKey(1)
            if key_input != -1:
                break

        st_device.acquisition_stop()
        st_datastream.stop_acquisition()

    except Exception as exception:
        print(exception)

メイン処理

  1. コールバッククラスのインスタンス作成:

    my_callback = CMyCallback()
    cb_func = my_callback.datastream_callback
    
  2. StApiの初期化と接続:

    st.initialize()
    st_system = st.create_system()
    st_device = st_system.create_first_device()
    print('Device=', st_device.info.display_name)
    
  3. データストリームの作成とコールバック登録:

    st_datastream = st_device.create_datastream()
    callback = st_datastream.register_callback(cb_func)
    
  4. 画像取得の開始と表示:

    st_datastream.start_acquisition()
    st_device.acquisition_start()
    
    print("To terminate, focus on the OpenCV window and press any key.")
    while True:
        output_image = my_callback.image
        if output_image is not None:
            cv2.imshow('image', output_image)
        key_input = cv2.waitKey(1)
        if key_input != -1:
            break
    
  5. 画像取得の停止:

    st_device.acquisition_stop()
    st_datastream.stop_acquisition()
    

OpenCVを利用した理由とメリット

理由

  1. 画像処理の強力なツール:

    • OpenCVは画像処理のための豊富な関数を提供しており、画像の変換や表示を簡単に行うことができます。
  2. リアルタイム処理:

    • 高速な画像処理が可能で、リアルタイムでの画像表示や解析に適しています。
  3. 広範なサポート:

    • OpenCVは多くのプラットフォームとプログラミング言語をサポートしており、他のシステムやライブラリと容易に統合できます。

メリット

  1. 簡単な実装:

    • OpenCVの関数を使用することで、複雑な画像処理を簡単に実装できます。
  2. 効率的な処理:

    • OpenCVはC++で実装されており、効率的に画像処理を行うことができます。
  3. 豊富な機能:

    • OpenCVには画像の読み込み、書き込み、表示、変換、フィルタリングなどの豊富な機能があり、開発者はこれらを利用して迅速にアプリケーションを開発できます。

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

関連資料

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