這是 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 ;
}