こちらの資料を読んでください。
コード全体の説明
このコードは、カメラから取得した画像データをOpenCVを使って処理し、表示するサンプルです。具体的には、以下の手順を実行します:
- StApiの初期化
- カメラへの接続
- 画像データの取得
- 画像データをOpenCV形式に変換
- Bayer画像形式をRGBに変換
- 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)
-
初期化と接続:
-
st.initialize()
でStApiを初期化し、st.create_system()
でシステムオブジェクトを作成、st_system.create_first_device()
で最初に検出されたデバイスに接続します。
-
-
データストリームの作成と画像取得の開始:
-
st_device.create_datastream()
でデータストリームオブジェクトを作成し、st_datastream.start_acquisition(number_of_images_to_grab)
で画像取得を開始します。
-
-
画像データの取得と処理:
-
st_datastream.retrieve_buffer()
でバッファを取得し、st_buffer.get_image()
で画像データを取得します。 -
pixel_format_info
を使用してピクセルフォーマット情報を確認し、Bayer画像の場合はcv2.cvtColor()
を使用してRGB形式に変換します。
-
-
画像の表示:
-
cv2.resize()
で画像をリサイズし、cv2.imshow()
で画像を表示します。
-
-
画像取得の停止:
-
st_device.acquisition_stop()
とst_datastream.stop_acquisition()
で画像取得を停止します。
-
OpenCVを利用した理由とメリット
理由
-
画像処理の強力なツール:
- OpenCVは、画像処理のための豊富な関数を提供しており、Bayer画像のRGB変換やフィルタリング、エッジ検出など多岐にわたる処理を簡単に実行できます。
-
リアルタイム処理:
- 高速な画像処理が可能であり、リアルタイムでの画像表示や処理に適しています。
-
広範なサポート:
- OpenCVは多くのプログラミング言語やプラットフォームでサポートされており、他のシステムやライブラリと容易に統合できます。
メリット
-
簡単な実装:
- OpenCVの関数を使用することで、複雑な画像処理アルゴリズムを簡単に実装できます。
-
効率的な処理:
- OpenCVは内部で最適化されており、効率的に画像処理を行うことができます。
-
豊富な機能:
- 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()
で取得したデータをそのまま表示しています。
関連資料