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를 성공적으로 받은 적이 있나요?