ライブ表示と画像のオーバーレイ表示
概要
OpenCVでは表示画像に対して、オーバーレイ処理で画像や図形を重ねて描写する事が可能です。寸法測定や位置合わせで使用する場合はカメラから取得したワークの画像上に、標準となる寸法や位置を示すオーバーレイ画像を重ねることで、視覚的に確認や評価が可能となります。特に、複雑な形状の製品や精密な位置合わせが求められる場合、オーバーレイ画像を利用することで、より迅速かつ正確な評価が行えます。 そのほかにもタイムスタンプ情報を表示し、同時に録画する事でトレーサビリティ目的でも使用する事ができます。
出力結果
プログラム全体
#解説1
import cv2
#解説2
cap = cv2.VideoCapture(0)
#解説3
overlay_img = cv2.imread('overlay.png', -1)
#解説4
while True:
# フレームをキャプチャ
ret, frame = cap.read()
if not ret:
break
# オーバーレイ画像をフレームと同じサイズにリサイズ
overlay_img_resized = cv2.resize(overlay_img, (frame.shape[1], frame.shape[0]))
# オーバーレイ画像が透明な部分でマスクを作成(アルファ値が0より大きい部分)
mask = overlay_img_resized[:,:,3] > 0
# マスクを適用してオーバーレイ画像をフレームに追加
frame[mask] = overlay_img_resized[:,:,:3][mask]
# 結果を表示
cv2.imshow('Overlay', frame)
# 'q'キーが押されたらループから抜ける
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#解説5
# キャプチャをリリースし、ウィンドウを閉じる
cap.release()
cv2.destroyAllWindows()
解説
解説1:モジュールのインポート
import cv2
import numpy as np
PythonのOpenCVライブラリをインポートしています。OpenCVは、画像処理やコンピュータビジョンに関する機能を提供するオープンソースのライブラリです。このライブラリをインポートすることで、後のコードでOpenCVの機能を使うことができます。例えば、画像の読み込み、変換、保存等、画像処理に関連する多くの機能を利用することができます。
解説2:ビデオキャプチャの開始
# カメラのビデオキャプチャを開始
cap = cv2.VideoCapture(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: オーバーレイ画像の読み込み
# オーバーレイ画像を読み込む
overlay_img = cv2.imread('overlay.png', -1)
cv2.imread
関数を使用してオーバーレイする画像を読み込んでいます。第1引数のoverlay.png
は画像ファイルの名前(またはパス)を指し、この場合はpythonのソースファイルと同じディレクトリかつ実行のルートディレクトリとなっています、第2引数の-1
は画像をアルファ値(透明度情報)付きで読み込むことを指示しています。
解説4: メインループ - フレームのキャプチャとオーバーレイ
while True:
# フレームをキャプチャ
ret, frame = cap.read()
if not ret:
break
# オーバーレイ画像をフレームと同じサイズにリサイズ
overlay_img_resized = cv2.resize(overlay_img, (frame.shape[1], frame.shape[0]))
# オーバーレイ画像が透明な部分でマスクを作成(アルファチャンネルが0より大きい部分)
mask = overlay_img_resized[:,:,3] > 0
# マスクを適用してオーバーレイ画像をフレームに追加
frame[mask] = overlay_img_resized[:,:,:3][mask]
# 結果を表示
cv2.imshow('Overlay', frame)
# 'q'キーが押されたらループから抜ける
if cv2.waitKey(1) & 0xFF == ord('q'):
break
ここではカメラの各フレームを取得&オーバレイ処理&表示を行うためのループ処理をしています。まず、 cap.read()
でカメラから1フレームを読み込み、この関数ではret
にフレームの読み込みが成功したかどうかを示すTrue/FalseのBoolean値、frame
は読み込んだフレームのデータが格納されます。その後ret
を参照して読み込みが失敗ていた場合はループ処理を抜けます。
次にcv2.resize
で解説3で取得したオーバーレイ画像をカメラの画像と同じサイズにリサイズします。
そして、overlay_img_resized[:,:,3] > 0でマスクを作成します。このマスクは、オーバーレイ画像のアルファ値(透明度情報)が0より大きい、つまり透明でない部分を取得します。
frame[mask] = overlay_img_resized[:,:,:3][mask]で前述のマスクを使用してオーバーレイ画像を追加します。ここでは透明ではない部分だけがフレームコピーされます。
cv2.imshow('camera', frame)
でオーバレイされたフレームを画面に表示します。ここで'Overlay'は表示ウィンドウの名前です。 cv2.waitKey(1)
はキーボードからの入力を1ミリ秒待ちます。そして& 0xFF == ord('q')
の部分で、入力されたキーが'q'であればループを抜ける(プログラムを終了する)ようにしています。
補足:オーバレイをどう行うか
カメラメーカーが提供するSDKでも下記のサンプルのようにオーバーレイ機能があります。
https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/dotnet_35/finding-a-laser-point.html
同様の視覚的強調表示をOpenCVだけで行うためには、画像取り込み後の画像処理が必要となり、リアルタイム性が損なわれます。そのため、リアルタイム処理が必要なオーバーレイの場合はできるだけメーカー製のSDKを使った方が望ましいです。
解説5:リソースの解放
cap.release()
cv2.destroyAllWindows()
ここでは、使用が終わったリソースを適切に解放しています。
まず、 cap.release()
はプログラムが終了した際にリソースのリークを防ぐためにカメラデバイスを解放します。この呼び出しを忘れると、カメラが他のプログラムから使用できなくなる可能性があります。
最後にcv2.destroyAllWindows()
は、OpenCVで開かれた全てのウィンドウを閉じます。