Это известная проблема с потоками RTSP и трудоемкими алгоритмами, такими как платформы глубокого обучения. Вы теряете синхронизацию, если для обработки отдельных кадров требуется больше времени, чем частота кадров вашего потока. Между реальностью и запечатленными изображениями увеличивается задержка.
Есть два возможных решения этой проблемы.
Кодекс говорит сам за себя.
Вы можете использовать GStreamer или FFmpeg, чтобы открыть поток.
Потоки RTSP обычно сжимаются с помощью H264. Поэтому ваша распаковка чувствительна к проблемам времени, например, к остановке потоков на некоторое время.
Чтобы запустить приложение, вам необходимо:
$ sudo apt-get install codeblocks
) Для потока RTSP используйте только проводное соединение Ethernet. Wi-Fi может работать нестабильно.
Поскольку протокол RTSP чувствителен даже к одному отсутствующему кадру, поток может легко выйти из строя.
Если вы используете поток в приложении глубокого обучения, настройте разрешение и частоту кадров в соответствии с требованиями модели глубокого обучения.
Не рекомендуется отправлять поток 1280x960 со скоростью 30 кадров в секунду, если ваша модель имеет вход 416x416 и обработка одного кадра занимает 200 мс.
Это требует только дополнительной памяти и вычислительной мощности.
Если вы хотите транслировать UDP или TCP, заранее убедитесь, что потоки работают с командной строкой. Если нет, то они точно не будут работать в OpenCV. Часто ошибки вызваны кодировкой в конвейере, адресами или отсутствующими модулями. Если вам нужно установить дополнительные модули GStreamer, вам также потребуется пересобрать OpenCV! Для получения дополнительной информации посетите наш сайт.
Чтобы запустить приложение, загрузите файл проекта RTSPcam.cbp в Code::Blocks.
Если вы используете Jetson Nano , вам необходимо изменить место, где OpenCV сохранил свои файлы заголовков, на /usr/include/opencv4
В строке 16 файла main.cpp открывается поток.
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);
Отправитель: RaspiCam с ОС Raspberry Pi Buster
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
Отправитель: RaspiCam с ОС Raspberry Pi Bullseye .
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);
Отправитель: RaspiCam с ОС Raspberry Pi Buster
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
Отправитель: RaspiCam с ОС Raspberry Pi Bullseye .
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 ;
}