LoginSignup
0
0

OMRON SENTECカメラ Python Buildup (4) grab_opencv.py

Last updated at Posted at 2024-05-24

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

コード全体の説明

このコードは、カメラから取得した画像データをOpenCVを使って処理し、表示するサンプルです。具体的には、以下の手順を実行します:

  1. StApiの初期化
  2. カメラへの接続
  3. 画像データの取得
  4. 画像データをOpenCV形式に変換
  5. Bayer画像形式をRGBに変換
  6. OpenCVで画像をプレビュー

コードの詳細分析

インポートと設定

import cv2
import numpy as np
import stapipy as st

# Number of images to grab
number_of_images_to_grab = 100

# Image scale when displaying using OpenCV.
DISPLAY_RESIZE_FACTOR = 0.3
  • cv2: OpenCVライブラリをインポートします。
  • numpy: 画像データの処理に使用するため、NumPyライブラリをインポートします。
  • stapipy: StApiライブラリをインポートします。

メイン部分

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

    st_datastream.start_acquisition(number_of_images_to_grab)
    st_device.acquisition_start()

    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]))

                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):
                    continue

                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)
                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_device.create_datastream()でデータストリームオブジェクトを作成し、st_datastream.start_acquisition(number_of_images_to_grab)で画像取得を開始します。
  3. 画像データの取得と処理:

    • st_datastream.retrieve_buffer()でバッファを取得し、st_buffer.get_image()で画像データを取得します。
    • pixel_format_infoを使用してピクセルフォーマット情報を確認し、Bayer画像の場合はcv2.cvtColor()を使用してRGB形式に変換します。
  4. 画像の表示:

    • cv2.resize()で画像をリサイズし、cv2.imshow()で画像を表示します。
  5. 画像取得の停止:

    • st_device.acquisition_stop()st_datastream.stop_acquisition()で画像取得を停止します。

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

理由

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

    • OpenCVは、画像処理のための豊富な関数を提供しており、Bayer画像のRGB変換やフィルタリング、エッジ検出など多岐にわたる処理を簡単に実行できます。
  2. リアルタイム処理:

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

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

メリット

  1. 簡単な実装:

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

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

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

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

カメラが白黒で、mono 8bitの場合のシンプルコード

以下は、白黒カメラ用にシンプル化したコードです。画像データが8ビットのモノクロであることを前提としています。

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_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]))

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

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

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

                # 画像をリサイズして表示
                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)

このコードでは、カラー画像の変換や不要な処理を省略し、モノクロ画像の表示に焦点を当てています。st_image.get_image_data()で取得したデータをそのまま表示しています。

関連資料

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