Pythonエンジニアのスキルの標準化のため、カメラインタフェースについて書く。
想定する読者
- Linux のPythonユーザー
USBカメラ
ls /dev/video*
で表示されているはずです。
import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("カメラを開くことができませんでした")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("フレームを取得できませんでした")
break
cv2.imshow('Camera', frame)
# 'q' キーが押されたらループを終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Ubutuでのアプリケーション例
- cheese
- VLC media player
MIPI (CSI-2)
CSI-2 のインタフェースでカメラを接続する例
Raspberry Pi4
RaspberryPi についていえば、「インタフェース」が頻繁に記事を書いているので、それらを参照するとよい。
NVIDIA Jetson
Jetson AGX Orinの仕様を見てください。
CSI カメラのインタフェースが書かれています。
StereoLab ZED2i カメラ
3Dカメラのインタフェースの例として、ZED2iカメラを示します。
このカメラのSDKでは、以下のことができます。
・RGB画像を取得する。
・深度画像を取得する。
・撮影した領域の点群データを取得する。
・内蔵のIMUのデータを取得する。
・データの取得時刻を返す。
・物体検出結果を3Dでの座標として返す。
・そのため、通常のカメラとは異なるインタフェースになっています。
qiitaでZED-SDKのタグがついた記事
にZED SDKの解説記事があります。
そのほかの3Dカメラ
3Dカメラのプロバイダは、たいがいの場合、C++やPythonで使えるSDKを提供しています。
それらのSDKでは、StereoLab ZED2i カメラと同様に
・撮影した領域の点群データを取得する。
・物体検出結果を3Dでの座標として返す
などを同様に実装している場合があります。
GMSL2カメラ
GMSLカメラをなんとなく理解する
自動運転カメラの高負荷、その原因はLinuxカーネルのどこに?
Jetson へのGMSLカメラを調査中
Gstreamer
pipelineで動画入力からの処理を扱おうとする枠組みです。
pipelineに分割しないシングルスレッドの処理では
- フレームの読み込み
- 画像のリサイズ
- 検出処理
- 検出結果の表示
が同一のスレッドで動作します。
そのため、検出処理をしているときに、他のスレッドでフレームの読み込みをすることがありません。
マルチコアを用いているのにその利点が活用できていないことになります。
GSTEAMERを使うと、pipeline 内の各エレメントが別のスレッドで動作するため、
マルチコアの恩恵を受けやすくなります。
pipelineで動画入力からの処理を扱おうとする枠組みです。
pipelineに分割しないシングルスレッドの処理では
- フレームの読み込み
- 画像のリサイズ
- 検出処理
- 検出結果の表示
が同一のスレッドで動作します。
そのため、検出処理をしているときに、他のスレッドでフレームの読み込みをすることがありません。
マルチコアを用いているのにその利点が活用できていないことになります。
GSTEAMERを使うと、pipeline 内の各エレメントが別のスレッドで動作するため、
マルチコアの恩恵を受けやすくなります。
NVIDIA はGStreamer を基盤としてDeepStreamを提供しています。
GStreamer, DeepStream については、それぞれ検索してみてください。
OpenCVでGstreamerを使うためには
PythonでOpenCVからGStreamerを使うためのOpenCV4.6.0のBuildについて
How to install with GStreamer support
V4L2
ROS2でのV4Lカメラ
argus カメラ
第2話 ビデオ入力(CSI接続のLibargus準拠カメラ)
Libargus Camera API
Jetsonのカメラドライバを書く[Argus撮影編]
RTSP(Real Time Streaming Protocol)
ストリーミングデータの配信のプロトコールです。
RTSP Client for Python
未調査です。
ROS2でカメラ画像をpublishする
ROS2では、ノード間で、messageをpublish, subsribe(あるいはlisten)することで通信することができます。
H.264
opencv でH.264で書き込む
cv2.VideoWriterでH264 codecを使う。
opencv でH.264で読み込む
OpenCV VideoCapture with H264 CODEC
画像認識では画像が取得できることが出発点です。
ボードがそのカメラを認識させること
ネットワークの場合プロトコールに対応させること
デコード処理を高速化させること
(デコード処理のアクセラレータを使うこと)
GPUを使う処理の場合、処理を一貫してGPUで行わせることで、CPU-GPU間のトラフィックを発生させないことです。
カメラの撮影条件を改善すること
カメラの撮影条件は、ゲイン設定、露光時間など多数あります。
それらを最適な条件に保つことが、画像認識の出発点になります。
黒つぶれ・白飛び画像では、なにもできなくなってしまいます。
データの遅延を減らすこと
- データ処理をpipelineにすることで、マルチコアのCPUの利点を引き出すこと
- 処理の中でのバッファリングの影響を減らすこと
- jpeg エンコード jpeg デコードをpipeline に含めないこと
- CPU, GPU間のデータの転送を減らすこと
- CSI2カメラインタフェースから直接GPUに転送すること
Reading CSI camera input directly to GPU memory のような要望はでている。