これは、RTSP ストリームと、深層学習フレームワークなどの時間のかかるアルゴリズムに関する既知の問題です。個々のフレームの処理にストリームのフレーム レートよりも長い時間がかかると、同期が失われます。現実とキャプチャされた画像の間の遅延が増加しています。
この問題には 2 つの解決策が考えられます。
コード自体がすべてを物語っています。ストリームを開くには、FFmpeg または GStreamer を使用できます。
接続するカメラの数に制限はありません。カメラは 1 台だけでも構いません。
ただし、カメラの数が増えると、すべての個別のスレッドにアクセスするために必要な CPU 時間が増加します。
アプリケーションを実行するには、次のことを行う必要があります。
次のように cmake でビルド パスを作成し、プロジェクトをビルドします。
rm -rf build && mkdir -p build && cd build
cmake .. && make
あるいは、インストールする必要がある Code::Blocks を使用してプロジェクトをビルドすることもできます ( $ sudo apt-get install codeblocks
)。
RTSP ストリームには有線イーサネット接続のみを使用してください。 Wi-Fiが不安定になる場合があります。
RTSP プロトコルは 1 つのフレームの欠落にも敏感であるため、ストリームは簡単にクラッシュする可能性があります。
深層学習アプリでストリームを使用している場合は、深層学習モデルの要件に合わせて解像度とフレーム レートを調整します。
モデルに 416x416 入力があり、1 つのフレームの処理に 200 ミリ秒かかる場合、1280x960 ストリームを 30 FPS で送信することはお勧めできません。追加のメモリと処理能力がかかるだけです。
すべてのカメラの解像度が同じであることを確認してください。この例では、OpenCV 連結アルゴリズムはさまざまな解像度の影響を受けます。異なる幅または高さに直面すると例外がスローされます。
カメラはスレッドによって相互に同期されないことに注意してください。ラグが若干異なる場合があります。
UDP または TCP をストリーミングする場合は、事前にストリームがコマンド ライン プロンプトで機能することを確認してください。そうしないと、OpenCV では確実に動作しません。多くの場合、エラーはパイプライン内のコーディング、アドレス、またはモジュールの欠落によって発生します。追加の GStreamer モジュールをインストールする必要がある場合は、OpenCV も再構築する必要があります。詳細については、当社の Web サイトをご覧ください。
アプリケーションを実行するには、Code::Blocks にプロジェクト ファイル MultiThread.cbp をロードします。
Jetson Nano を使用している場合は、OpenCV がヘッダー ファイルを保存している場所を/usr/include/opencv4
に変更する必要があります。
main.cpp の 23 行目でストリームが定義されています。
Grb1->Init("rtsp://192.168.178.129:8554/test/");
Grb1->Init("udpsrc port=5200 ! application/x-rtp, media=video, clock-rate=90000, payload=96 ! rtpjpegdepay ! jpegdec ! videoconvert ! appsink", cv::CAP_GSTREAMER);
送信者: Raspberry Pi Buster OS を搭載した RaspiCam
gst-launch-1.0 -v v4l2src device=/dev/video0 num-buffers=-1 ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! jpegenc ! rtpjpegpay ! udpsink host=192.168.178.84 port=5200
送信者: Raspberry Pi Bullseye OS を搭載した RaspiCam
gst-launch-1.0 -v libcamerasrc ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! jpegenc ! rtpjpegpay ! udpsink host=192.168.178.84 port=5200
host=192.168.178.84
受信者の IP アドレスであることに注意してください。
Grb1->Init("tcpclientsrc host=192.168.178.129 port=5000 ! jpegdec ! videoconvert ! appsink", cv::CAP_GSTREAMER);
送信者: Raspberry Pi Buster OS を搭載した RaspiCam
gst-launch-1.0 -v v4l2src device=/dev/video0 num-buffers=-1 ! video/x-raw,width=640,height=480, framerate=30/1 ! videoconvert ! jpegenc ! tcpserversink host=192.168.178.32 port=5000
送信者: Raspberry Pi Bullseye OS を搭載した RaspiCam
gst-launch-1.0 -v libcamerasrc ! video/x-raw,width=640,height=480, framerate=30/1 ! videoconvert ! jpegenc ! tcpserversink host=192.168.178.32 port=5000
host=192.168.178.32
送信者の IP アドレスであることに注意してください。
Grb1->Init("libcamerasrc ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! videoscale ! video/x-raw, width=640, height=480 ! appsink", cv::CAP_GSTREAMER);
Grb1->Init("v4l2src device=/dev/video0 ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! videoscale ! video/x-raw, width=640, height=480 ! appsink", cv::CAP_GSTREAMER);
Grb1->Init(0);
Grb1->Init(0); //if RaspiCam is not connected
Grb2->Init(1); //if RaspiCam is connected