Es handelt sich um ein bekanntes Problem bei RTSP-Streams und zeitaufwändigen Algorithmen wie Deep-Learning-Frameworks. Sie geraten aus der Synchronisierung, wenn die Verarbeitung einzelner Frames länger dauert als die Framerate Ihres Streams. Es kommt zu einer zunehmenden Verzögerung zwischen der Realität und den aufgenommenen Bildern.
Es gibt zwei mögliche Lösungen für dieses Problem.
Der Code spricht für sich.
Sie können entweder GStreamer oder FFmpeg verwenden, um den Stream zu öffnen.
RTSP-Streams werden normalerweise mit H264 komprimiert. Daher reagiert Ihre Dekomprimierung empfindlich auf Zeitprobleme, z. B. wenn Threads für einige Zeit angehalten werden.
Um die Anwendung auszuführen, müssen Sie:
$ sudo apt-get install codeblocks
) Verwenden Sie für Ihren RTSP-Stream nur eine kabelgebundene Ethernet-Verbindung. WLAN kann instabil sein.
Da das RTSP-Protokoll bereits auf einen einzigen fehlenden Frame reagiert, kann der Stream leicht abstürzen.
Wenn Sie den Stream in einer Deep-Learning-App verwenden, passen Sie Ihre Auflösung und Bildrate an die Anforderungen des Deep-Learning-Modells an.
Es ist keine gute Idee, einen 1280x960-Stream mit 30 FPS zu senden, wenn Ihr Modell über einen 416x416-Eingang verfügt und 200 mSek. benötigt, um einen einzelnen Frame zu verarbeiten.
Es kostet nur zusätzlichen Speicher und Rechenleistung.
Wenn Sie UDP oder TCP streamen möchten, vergewissern Sie sich vorher, dass die Streams mit der Befehlszeilenaufforderung funktionieren. Wenn nicht, funktionieren sie sicherlich nicht in OpenCV. Häufig werden Fehler durch die Codierung in der Pipeline, die Adressen oder fehlende Module verursacht. Wenn Sie zusätzliche GStreamer-Module installieren müssen, müssen Sie auch Ihr OpenCV neu erstellen! Weitere Informationen finden Sie auf unserer Website.
Um die Anwendung auszuführen, laden Sie die Projektdatei RTSPcam.cbp in Code::Blocks.
Wenn Sie einen Jetson Nano verwenden, müssen Sie den Speicherort, an dem OpenCV seine Header-Dateien gespeichert hat, in /usr/include/opencv4
ändern
In Zeile 16 in main.cpp wird der Stream geöffnet.
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);
Absender: RaspiCam mit Raspberry Pi Buster OS
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
Absender: RaspiCam mit Raspberry Pi Bullseye OS
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
Beachten Sie, host=192.168.178.84
die IP-Adresse des Empfängers ist.
cam.Open("tcpclientsrc host=192.168.178.129 port=5000 ! jpegdec ! videoconvert ! appsink", cv::CAP_GSTREAMER);
Absender: RaspiCam mit Raspberry Pi Buster OS
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
Absender: RaspiCam mit Raspberry Pi Bullseye OS
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
Beachten Sie, host=192.168.178.32
die IP-Adresse des Absenders ist.
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 ;
}