デバイスオープンとデバイスリストの取得

概要

デバイスを複数台接続したとき、どのカメラが接続されているか把握することは重要です。ここでは利用可能なデバイスを特定し、デバイスをオープンし制御するための解説をしています。

出力結果

利用可能なUVCデバイスをオープン

プログラム全体

#解説1 import cv2 #解説2 def get_available_cameras(max_devices = 10): # この関数は最初のmax_devicesデバイスをチェックし、利用可能なデバイスのリストを返します。 available_devices = [] for i in range(max_devices): cap = cv2.VideoCapture(i) if cap is None or not cap.isOpened(): print('警告: ビデオソースを開けません: ', i) else: print('成功: ビデオソースを見つけました: ', i) available_devices.append(i) cap.release() # デバイスを開放します。 return available_devices #解説3 def open_and_capture(device_id): # この関数はデバイスを開き、1フレームをキャプチャします。キャプチャ後、デバイスを開放します。 cap = cv2.VideoCapture(device_id) ret, frame = cap.read() cap.release() # デバイスを開放します。 if ret: return frame # キャプチャ成功時、フレームを返します。 else: return None # キャプチャ失敗時、Noneを返します。 #解説4 # 利用可能なカメラデバイスのリストを取得します。 devices = get_available_cameras() #解説5 # 利用可能な各デバイスを開き、1フレームをキャプチャします。 for device in devices: frame = open_and_capture(device) if frame is not None: cv2.imshow('Device No:'+str(device) , frame) # キャプチャしたフレームを表示します。 cv2.waitKey(0) # キーボード入力を待ちます。 cv2.destroyAllWindows() # すべてのウィンドウを閉じます。

解説

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

import cv2

最初に行うのは、必要なライブラリのインポートです。このコードでは、cv2という名前でOpenCVライブラリをインポートしています。OpenCVは、デバイスの制御だけでなく画像処理やコンピュータビジョンのタスクを行うための強力なライブラリです。

解説2: 利用可能なカメラデバイスの取得

def get_available_cameras(max_devices = 10): available_devices = [] for i in range(max_devices): cap = cv2.VideoCapture(i) if cap is None or not cap.isOpened(): print('警告: ビデオソースを開けません: ', i) else: print('成功: ビデオソースを見つけました: ', i) available_devices.append(i) cap.release() return available_devices

この関数は、利用可能なすべてのUVCカメラを探しリストを返します。複数のカメラをシステムに利用する時に、利用可能なカメラをリストするのに使用します。まず、利用可能なデバイスのリストを格納するための空のリストavailable_devicesを作成します。 その後、引数max_devicesで指定された数だけ(ここでは最大10台)、cv2.VideoCaptureでカメラを開き、使用できるか確認をしています。使用な可能な状態であれば、そのデバイス番号をavailable_devicesリストに追加し、'成功: ビデオソースを見つけました: 'を表示しています。その後、cap.release()を使用して、他のプロセスや後続の操作でカメラが使用できるようにするためにカメラのリソースを解放します。

補足:available_devicesについて

TheImagingSource社のSDK(ICImagingControl)で接続しているカメラ一覧を表示する場合は、IC_GetUniqueNamefromList()の関数が利用できます。これを使うと、カメラ型番とシリアル番号も簡単に取得することができます。ソフトウェアからシリアル番号や型番で複数台のUVCカメラを個別に認識できると、デバイスの管理が容易になります。
https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/list-devices.html

解説3: デバイスからのフレームのキャプチャ

def open_and_capture(device_id): cap = cv2.VideoCapture(device_id) ret, frame = cap.read() cap.release() if ret: return frame else: return None

この関数は、指定されたデバイスIDのUVCカメラを開き、カメラの映像を1フレーム取得します。 まず、cv2.VideoCapture(device_id)を使用して、指定されたIDのカメラを開きます。ここで、device_idはカメラのデバイス番号を指します。デバイス番号は通常、システムがカメラを認識する順番に基づいています。 次に、cap.read()を使用して、カメラから1フレームの画像を取得します。cap.read()は、カメラから画像を読み込むためのメソッドで、ここではretframeのそれぞれに値を返します。retは画像の読み込みが成功したかどうかを示すブール値(TrueまたはFalse)、frameは取得した画像データです。デバイスが開けなかった場合、または何らかの理由でフレームを取得できなかった場合は、Noneを返します。

解説4: 利用可能なカメラデバイスのリストの取得

devices = get_available_cameras()

解説2で定義したget_available_cameras関数を呼び出して、利用可能なカメラデバイスのリストを取得します。このリストは、次の解説5で各デバイスからフレームを取得するために使用されます。

解説5: 各デバイスからのフレームのキャプチャと表示

for device in devices: frame = open_and_capture(device) if frame is not None: cv2.imshow('Device No:'+str(device) , frame) # キャプチャしたフレームを表示します。 cv2.waitKey(0) # キーボード入力を待ちます。 cv2.destroyAllWindows() # すべてのウィンドウを閉じます。

ここでは、解説4で取得した使用可能なカメラデバイスのリストdevicesから各要素を取得するためにforループを行います。この要素devicesは、カメラデバイスのIDです。ループ処理の中で解説3で記載したopen_and_capture(device)関数を呼び出して、指定されたデバイスIDのカメラからフレームをキャプチャします。この関数は、フレームのキャプチャが成功した場合にはキャプチャしたフレームを、失敗した場合にはNoneを返します。 次に、キャプチャしたフレームが正常に取得できた場合、cv2.imshowを使用してそのフレームを表示します。 ループが終了した後、cv2.waitKey(0)を使用して、ユーザーからのキーボード入力を待ちます。この関数は、ユーザーがキーを押すまでプログラムを一時停止します。この間、ユーザーは各カメラのキャプチャしたフレームを見ることができます。最後に、cv2.destroyAllWindows()を使用して、すべてのウィンドウを閉じます。これは、プログラムが終了する前にリソースを適切に解放するために必要となります。

補足:OpenCVとよく見るcv2.waitKey(0)について

OpenCVをプログラムに用いる場合は、'q'キーが押されたらプログラムを終了するというプログラムをよく見ると思います。その理由としては、プログラムがウィンドウを開いて画像を表示した後、すぐに次の命令に進んでしまい、最終的にプログラムが終了してウィンドウが閉じられるためです。cv2.waitKey(0)がないと、画像が表示されたかどうかを確認する時間がないため、画像が表示されているように見えない場合があります。