これは、RTSP ストリームと、深層学習フレームワークなどの時間のかかるアルゴリズムに関する既知の問題です。個々のフレームの処理にストリームのフレーム レートよりも長い時間がかかると、同期が失われます。現実とキャプチャされた画像の間の遅延が増加しています。
この問題には 2 つの解決策が考えられます。
コード自体がすべてを物語っています。
GStreamer または FFmpeg を使用してストリームを開くことができます。
RTSP ストリームは通常、H264 で圧縮されます。したがって、解凍は、スレッドがしばらく停止するなど、タイミングの問題に敏感になります。
アプリケーションを実行するには、次のことを行う必要があります。
$ sudo apt-get install codeblocks
) RTSP ストリームには有線イーサネット接続のみを使用してください。 Wi-Fiが不安定になる場合があります。
RTSP プロトコルは 1 つのフレームの欠落にも敏感であるため、ストリームは簡単にクラッシュする可能性があります。
深層学習アプリでストリームを使用している場合は、深層学習モデルの要件に合わせて解像度とフレーム レートを調整します。
モデルに 416x416 入力があり、1 つのフレームの処理に 200 ミリ秒かかる場合、1280x960 ストリームを 30 FPS で送信することはお勧めできません。
追加のメモリと処理能力がかかるだけです。
UDP または TCP をストリーミングする場合は、事前にストリームがコマンド ライン プロンプトで機能することを確認してください。そうしないと、OpenCV では確実に動作しません。多くの場合、エラーはパイプライン内のコーディング、アドレス、またはモジュールの欠落によって発生します。追加の GStreamer モジュールをインストールする必要がある場合は、OpenCV も再構築する必要があります。詳細については、当社の Web サイトをご覧ください。
アプリケーションを実行するには、Code::Blocks にプロジェクト ファイル RTSPcam.cbp をロードします。
Jetson Nano を使用している場合は、OpenCV がヘッダー ファイルを保存している場所を/usr/include/opencv4
に変更する必要があります。
main.cpp の 16 行目でストリームが開きます。
cam.Open("rtsp://192.168.178.129:8554/test/");
cam.Open("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 アドレスであることに注意してください。
cam.Open("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 アドレスであることに注意してください。
cam.Open("libcamerasrc ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! videoscale ! video/x-raw, width=640, height=480 ! appsink", cv::CAP_GSTREAMER);
cam.Open("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);
cam.Open(0);
cam.Open(0); //if RaspiCam is not connected
cam.Open(1); //if RaspiCam is connected
cam.Open("James.mp4");
cam.Open("/home/pi/Pictures/Plants");
cam.Open("/home/pi/Pictures/Garden.jpg");
int main ()
{
cv::Mat frame;
RTSPcam cam;
cv::namedWindow ( " Camera " , cv::WINDOW_AUTOSIZE);
cam. Open ( " rtsp://192.168.178.129:8554/test/ " ); // you can dump anything OpenCV eats. (cv::CAP_ANY) BTW,OpenCV first tries FFmpeg
while ( true )
{
if (!cam. GetLatestFrame (frame)){
cout << " Capture read error " << endl;
break ;
}
// place here your time consuming algorithms
// cout << cam.CurrentFileName << endl;
// show frame
cv::imshow ( " Camera " ,frame);
char esc = cv::waitKey ( 2 );
if (esc == 27 ) break ;
}
cv::destroyAllWindows () ;
return 0 ;
}