Это известная проблема с потоками RTSP и трудоемкими алгоритмами, такими как платформы глубокого обучения. Вы теряете синхронизацию, если для обработки отдельных кадров требуется больше времени, чем частота кадров вашего потока. Между реальностью и захваченными изображениями увеличивается задержка.
Есть два возможных решения этой проблемы.
Кодекс говорит сам за себя. Вы можете использовать GStreamer или FFmpeg, чтобы открыть поток.
Количество подключаемых камер не ограничено. Это может быть даже одна камера.
Однако чем больше камер, тем больше процессорного времени требуется для посещения всех отдельных потоков.
Чтобы запустить приложение, вам необходимо:
Создайте путь сборки и создайте проект с помощью cmake следующим образом:
rm -rf build && mkdir -p build && cd build
cmake .. && make
Альтернативно вы также можете собрать проект с помощью Code::Blocks, в который вам нужно его установить ( $ sudo apt-get install codeblocks
).
Для потока RTSP используйте только проводное соединение Ethernet. Wi-Fi может работать нестабильно.
Поскольку протокол RTSP чувствителен даже к одному отсутствующему кадру, поток может легко выйти из строя.
Если вы используете поток в приложении глубокого обучения, настройте разрешение и частоту кадров в соответствии с требованиями модели глубокого обучения.
Не рекомендуется отправлять поток 1280x960 со скоростью 30 кадров в секунду, если ваша модель имеет вход 416x416 и обработка одного кадра занимает 200 мс. Это требует только дополнительной памяти и вычислительной мощности.
Убедитесь, что все камеры имеют одинаковое разрешение. В этом примере алгоритм конкатенации OpenCV чувствителен к разным разрешениям. Он выдает исключение, когда сталкивается с разной шириной или высотой.
Обратите внимание, что камеры не синхронизируются между собой по потокам. У них могут быть немного разные лаги.
Если вы хотите транслировать UDP или TCP, заранее убедитесь, что потоки работают с командной строкой. Если нет, то они точно не будут работать в OpenCV. Часто ошибки вызваны кодировкой в конвейере, адресами или отсутствующими модулями. Если вам нужно установить дополнительные модули GStreamer, вам также потребуется пересобрать OpenCV! Для получения дополнительной информации посетите наш сайт.
Чтобы запустить приложение, загрузите файл проекта MultiThread.cbp в Code::Blocks.
Если вы используете Jetson Nano , вам необходимо изменить место, где OpenCV сохранил свои файлы заголовков, на /usr/include/opencv4
В строке 23 файла main.cpp определяется поток.
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);
Отправитель: 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-адрес получателя.
Grb1->Init("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-адрес отправителя.
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