ライブ表示と画像のROI設定

概要

OpenCVに置けるROI(Region of Interest、関心領域)設定とは、画像データ内から特定の領域を切り出す設定です。 カメラのROI(Region of Interest、関心領域)設定とは、特定の領域を切り出す設定の事です。 例えば、顔認識、物体追跡、動作検出などのタスクで利用され、ROI設定は画像の特定の部分に対して焦点を当てた処理を可能にします。

補足:カメラによるROIの違い

概要で解説したように、OpenCVのROIは画像データから切り出す処理をしましたが、産業用カメラ等に直接説設定できるROIはこういった切り出しの処理は行っておりません。では、どうしているかというと、イメージセンサを制御しする事で、初めから一部の領域しか撮影しないような設定を行って撮影しています。後者の最大のメリットは1枚の画像データが小さくなることです、OpenCVでは1920×1080で取り込んで、640×480切り出し処理を行っていた場合、産業カメラでは最初から640×480で撮影する事ができ、もっと高いフレームレートでの撮影&データ転送や、処理リソースをその他の画像処理やAI処理に使うなどが可能です。

補足2:画像のROIと画像処理のROI

概要、補足でROIとその種類に関して解説していますが、実はカメラや画像のROIと画像処理やフォーカス調整におけるROIは別の処理を表す事があります。画像処理やフォーカス調整のROIはどの領域をターゲットとして処理を行うかを決めるための設定領域です。例えば最近のスマートフォンのカメラでは人の顔や物体を検知するとボックスが表示されて、そこに合わせて明るさやフォーカス調整をしています、つまりそのボックスの範囲をROIとして画像処理を行っています。

出力結果

出力結果

プログラム全体

#解説1 import cv2 #解説2 # カメラの設定 cap = cv2.VideoCapture(0) # 0はカメラのデバイス番号 #解説3 # ROIの設定 roi_start_x, roi_start_y = 100, 100 # ROIの左上の座標を設定 roi_width, roi_height = 200, 200 # ROIの幅と高さを設定 #解説4 while True: # フレームを読み込む ret, frame = cap.read() # ROIを抽出 roi = frame[roi_start_y:roi_start_y+roi_height, roi_start_x:roi_start_x+roi_width] # ROIを表示する cv2.imshow('ROI', roi) # 'q'キーが押されたらループから抜ける if cv2.waitKey(1) & 0xFF == ord('q'): break #解説5 # キャプチャをリリースしてウィンドウを閉じる cap.release() cv2.destroyAllWindows()

解説

解説1: ライブラリのインポート

import cv2

PythonのOpenCVライブラリをインポートしています。OpenCVは、画像処理やコンピュータビジョンに関する機能を提供するオープンソースのライブラリです。このライブラリをインポートすることで、後のコードでOpenCVの機能を使うことができます。例えば、画像の読み込み、変換、保存等、画像処理に関連する多くの機能を利用することができます。

産業用UVCのすすめ

解説2:カメラの設定

# カメラの設定 cap = cv2.VideoCapture(0) # 0はカメラのデバイス番号

ここでは、UVCカメラを開いて、その映像を取得するためのオブジェクトを作成しています。cv2.VideoCapture(0)という関数は、引数にUVCカメラのIDを取り、そのカメラにアクセスするためのVideoCaptureオブジェクトを返しています。ここでの0は、通常はシステムに接続されているデフォルトのカメラ(通常は内蔵カメラ)を指しますが、使用しているカメラによって割り振られる番号が異なりますのでご注意ください。

補足:OpenCVにおけるデバイスID

デバイスが複数接続された場合、このIDは、いつも同じとは限りません。デバイスの起動やシステムへの接続順によって変わることがほとんどです。 TheImagingSource社が提供しているSDK(ICImagingControl)ではカメラ本体にシリアル番号が割り振られており、カメラ毎に設定が容易にできます。詳細は下記をご覧ください。
https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/open-with-built-in-dialog.html

解説3: ROIの設定

# ROIの設定 roi_start_x, roi_start_y = 100, 100 # ROIの左上の座標を設定 roi_width, roi_height = 200, 200 # ROIの幅と高さを設定

画像のROI(Region of Interest、関心領域)を設定しています。ROIは画像の中で特に切り出しを行いたい部分を指します。ここではROIの起点座標(x,y)を指定(x=100,y=100)しています、その後起点座標からどれだけの領域を表示するかを指定しています。なのでこの設定の場合は画面左上からx軸100px,y軸100pxを起点として、200×200の範囲を表示します。

解説4: フレームの取得と表示、プログラムの終了処理

while True: # フレームを読み込む ret, frame = cap.read() # ROIを取得 roi = frame[roi_start_y:roi_start_y+roi_height, roi_start_x:roi_start_x+roi_width] # ROIを表示する cv2.imshow('ROI', roi) # 'q'キーが押されたらループから抜ける if cv2.waitKey(1) & 0xFF == ord('q'): break

ここではwhile文でループ処理をしています。まず、 cap.read()でカメラから1フレームを読み込み、この関数ではretにフレームの読み込みが成功したかどうかを示すTrue/FalseのBoolean値、frameは読み込んだフレームのデータが格納されます。
frame[roi_start_y:roi_start_y+roi_height, roi_start_x:roi_start_x+roi_width]で、frameから指定された範囲を抽出します。ここでroi_start_y:roi_start_y+roi_heightはROIの開始行から終了行(行は画像の縦方向)、roi_start_x:roi_start_x+roi_widthはROIの開始列から終了列(列は画像の横方向)をを示しています。 後にcv2.imshow('ROI', roi)でROIを抽出したフレームを画面に表示します。ここでの'ROI'とは表示ウィンドウの名前です。 cv2.waitKey(1)はキーボードからの入力を1ミリ秒待ちます。そして& 0xFF == ord('q')の部分で、入力されたキーが'q'であればループを抜ける(プログラムを終了する)ようにしています。

補足:ROIを行うタイミングによる違い

上記の例ではカメラから出力された画像をPCに取り込んだ後に画像の切り出しを行っていますが、カメラメーカーのSDK(ICImagingControl)を使用するとカメラ側で画素切り出しを行うことができます。カメラから画像の特定の領域だけを処理するため、送信される画像データを初めから削減できます。これによって、出力画像1枚当たりの解像度を落とせば、設定可能フレームレートを向上させることができます。
  https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/roi-setting.html

解説5

# キャプチャをリリースしてウィンドウを閉じる cap.release() cv2.destroyAllWindows()

ここでは、使用が終わったリソースを適切に解放しています。 まず、 cap.release()はプログラムが終了した際にリソースのリークを防ぐためにカメラデバイスを解放します。この呼び出しを忘れると、カメラが他のプログラムから使用できなくなる可能性があります。 最後にcv2.destroyAllWindows()は、OpenCVで開かれた全てのウィンドウを閉じます。