这是 RTSP 流和深度学习框架等耗时算法的一个已知问题。如果单个帧的处理时间比流的帧速率长,您就会失去同步。现实与捕捉到的图像之间的延迟越来越大。
该问题有两种可能的解决方案。
代码本身就说明了一切。
您可以使用 GStreamer 或 FFmpeg 打开流。
RTSP 流通常使用 H264 进行压缩。因此,您的解压对于计时问题很敏感,例如线程暂停一段时间。
要运行该应用程序,您必须:
$ sudo apt-get install codeblocks
) 仅对 RTSP 流使用有线以太网连接。 Wi-Fi 可能不稳定。
由于 RTSP 协议对哪怕只是一帧丢失都很敏感,因此流很容易崩溃。
如果您在深度学习应用程序中使用流,请根据深度学习模型的要求调整分辨率和帧速率。
如果您的模型具有 416x416 输入并且需要 200 毫秒处理单个帧,那么以 30 FPS 发送 1280x960 流并不是一个好主意。
它只需要额外的内存和处理能力。
如果您想要流式传输 UDP 或 TCP,请确保流事先在命令行提示符下工作。如果没有,它们肯定无法在 OpenCV 中工作。错误通常是由管道中的编码、地址或丢失的模块引起的。如果您需要安装额外的 GStreamer 模块,您还需要重建 OpenCV!欲了解更多信息,请访问我们的网站。
要运行应用程序,请在 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操作系统的 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操作系统的 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操作系统的 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操作系统的 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 ;
}