Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ffmpeg和gstreamer的Opencv RTSP流媒体_Opencv_Ffmpeg_Gstreamer_Rtsp - Fatal编程技术网

使用ffmpeg和gstreamer的Opencv RTSP流媒体

使用ffmpeg和gstreamer的Opencv RTSP流媒体,opencv,ffmpeg,gstreamer,rtsp,Opencv,Ffmpeg,Gstreamer,Rtsp,我使用的是一台ip摄像机,它有主流(分辨率为1920x1080)和子流(分辨率为720x576)。我的目标是通过使用子流来检测运动,如果运动发生,我会从主流中拍摄一个snopshot,并对该图像进行一些处理。这是我的密码 VideoCapture cap; //video capture device captures the pal stream VideoCapture cap2; //video capture device captures the main str

我使用的是一台ip摄像机,它有主流(分辨率为1920x1080)和子流(分辨率为720x576)。我的目标是通过使用子流来检测运动,如果运动发生,我会从主流中拍摄一个snopshot,并对该图像进行一些处理。这是我的密码

    VideoCapture cap;   //video capture device captures the pal stream
    VideoCapture cap2;  //video capture device captures the main stream

    // cap.set(CV_CAP_PROP_BUFFERSIZE,1);
    // cap2.set(CV_CAP_PROP_BUFFERSIZE,1);
    //cap.set(CV_CAP_GSTREAMER_QUEUE_LENGTH,1);
    //cap2.set(CV_CAP_GSTREAMER_QUEUE_LENGTH,1);
    cap.open("rtsp://usr:pass@x.x.x.x:554/Streaming/Channels/2?transportmode=unicast&profile=Profile_2",CAP_FFMPEG);  //open substream
    cap2.open("rtsp:///usr:pass@x.x.x.x:554/Streaming/Channels/1?transportmode=unicast&profile=Profile_1",CAP_FFMPEG);  //open mainstream
    bool frame_read = false;
    int motion val;

    while (true) {
        frame_read = cap.read(rgb_im); //read the frame from substream
        //cap2.grab();
        if (!frame_read) {
            break;
        }
        cvtColor(rgb_im, gray_im, CV_BGR2GRAY);
        motion_val = detect_motion(gray_im);   //find the motion value

        if (motion_val > MOTION_OCCURRED)    //check if motion occurs
        {
            cap2>>frame_big;    //get one frame from the main stream
            process(frame_big);  //do processing
        }
        imshow("1", rgb_im);
            if (waitKey(1) >= 0)
                break;
    }`
当我打开带有CAP_FFMPEG标志的流时,延迟非常低(低于1秒)。如上所示,我定期阅读子流,如果发生运动,我阅读主流。但是我从主流中读到的帧与子流不同步。很可能我抓取了在缓冲区中等待的帧。所以我错过了运动的画面,我得到了一个更老的画面。我如何处理这个问题?不知何故,我必须使缓冲区大小为1帧,但我找不到任何方法

我试过了
cap.set(CV\u cap\u PROP\u BUFFERSIZE,1)但由于它需要DC1394支持,因此无法解决我的问题

其次,我在读取子流后尝试了
cap2.grab()
,但它增加了延迟(使延迟大约为3秒)


第三,我尝试用cv_cap_gstreamer flag
cap.open(“rtsp://usr:pass@x、 x.x.x:554/流媒体/频道/2传输模式=单播和配置文件=配置文件2”,CV\U CAP\U GSTREAMER)。它解决了我的缓冲问题。换句话说,当我从子流中检测到运动时,我能够从主流中捕捉到相同的瞬间。但对于gstreamer,我有大约3秒的巨大延迟,这对于我的情况来说是不可取的。(对于gstreamer,我尝试读取多个具有不同分辨率的rtsp流,延迟保持不变)当我将gstreamer与opencv一起使用时,如何解决延迟问题?

始终从两个流读取,但仅当在第一流中检测到运动时才处理第二流。顺便说一句,我认为,流在任何情况下都会不同步。谢谢你的回答。但我打开子流的原因是为了让阅读过程更快。主流的分辨率太高,不需要进行运动检测。如果我必须定期阅读主流,我只需将主流用于运动检测和处理。@DmitriSosnikReading应该很便宜,处理成本很高。