http://study.marearts.com/2015/05/opencv300-rc1-videocapture-example.html
http://study.marearts.com/2013/09/opencv-video-writer-example-source-code.html
But the video looks even broken video stream is shifted a bit.
So I use VLC library for stable receiving and show.
http://study.marearts.com/2015/09/opencv-rtsp-connection-using-vlc-library.html
This method is also good.
But It is cumbersome because it requires additional library file of VLC.
So again, let's solve this problem in OpenCV.
The method is to separately manage the RTSP receving part and drawing part.
New review code.
1. normal method. (This is not stable)
...
#include "opencv2/opencv.hpp" #include < string> using namespace std; using namespace cv; int main() { string streamUri = "rtsp://192.168.0.21:554/onvif/profile2/media.smp"; VideoCapture stream(streamUri); if (!stream.isOpened()){ cout << "error" << endl; return 0; } Mat image; while (1){ stream >> image; imshow("test", image); if (waitKey(30) >= 0) break; } return 0; }..
2. Receiving part threading(stable)
...#include "opencv2/opencv.hpp" #include < string> #include < list> #include < thread> using namespace std; using namespace cv; // RTSP receive buffer list list< Mat> frames; cv::VideoCapture stream2; bool isRun; // thread function for video getting and show void StreamThread(bool &isRun) { cv::Mat image; while (isRun){ stream2 >> image; frames.push_back(image.clone()); printf("%d mat stacked \n", frames.size()); } } int main(int, char) { //rtsp address string streamUri = "rtsp://192.168.0.21:554/onvif/profile2/media.smp"; stream2.open(streamUri); //open check if (!stream2.isOpened()){ cerr << "Stream open failed : " << streamUri << endl; return EXIT_FAILURE; } isRun = true; // thread run thread(StreamThread, isRun).detach(); //Mat draw only in the main function. while (isRun){ if (frames.size()>1){ Mat image = frames.front(); imshow("test", image); frames.pop_front(); if (waitKey(30) >= 0) break; } } isRun = false; return 0; }...
3. Drawing part threading
#include "opencv2/opencv.hpp" #include < string> #include < list> #include < thread> using namespace std; using namespace cv; // RTSP receive buffer list list< Mat> frames; bool isRun; // thread function for video show void drawFrame(bool &isRun) { while (isRun){ if (frames.size()>1){ Mat image = frames.front(); imshow("test", image); waitKey(1); frames.pop_front(); } } } int main(int, char) { //rtsp address string streamUri = "rtsp://192.168.0.21:554/onvif/profile2/media.smp"; VideoCapture stream(streamUri); //open check if (!stream.isOpened()){ cerr << "Stream open failed : " << streamUri << endl; return EXIT_FAILURE; } isRun = true; // thread run thread(drawFrame, isRun).detach(); cv::Mat image; //Mat get only in the main function. while (isRun){ stream >> image; frames.push_back(image.clone()); printf("%d mat stacked \n", frames.size()); } isRun = false; return 0; }...
Github
https://github.com/MareArts/OpenCV-RTSP-receiving-Test-in-thread-and-while-processing
Thank you.
μ§λ¬Έ μμ΅λλ€.
ReplyDeleteVLC νλ μ΄μ΄λ₯Ό ν΅ν΄ μ€νΈλ¦Όμ μ§νν ν
opencvλ₯Ό μ΄μ©ν΄ ν΄λΌμ΄μΈνΈ μμμ μμμ κ°μ Έμ€λ €κ³ νλλ°
μμλΆν° uri μ μμ΄ μλλ κ² κ°μ΅λλ€.
μ¦ string streamUri = "rtsp://192.168.0.21:554/onvif/profile2/media.smp";
VideoCapture stream(streamUri);
μ΄ λΆλΆμμ openμ΄ λμ§ μκ³ μλλ° νΉμ μ΄ λΆλΆμ λν΄μ μμλ κ²μ΄ μμΌμ κ°μ?
vlcλ‘λ ν΄λΉ μ£Όμκ° μ€ν°λ¦¬λ° λλμ?
Deleteopencvλ‘ rtspλ₯Ό μ±κ³΅μ μΌλ‘ λ°μ μ μ΄ μλμ?