当我使用rtsp camera stream

时间:2017-03-13 10:30:03

标签: c++ multithreading opencv rtsp

所以我目前正在开发一个需要在rtsp ip cam上进行面部识别的项目,我设法得到了没有问题的rtsp提要,但是当应用人脸识别时,视频输入速度太慢并且显示了很大的延迟,我甚至使用多线程来使其更好但是没有成功,这是我的代码我仍然是多线程问题的初学者,所以任何帮助都将受到赞赏。

    #include <iostream>
#include <thread>
#include "opencv2/opencv.hpp"

#include <vector>
using namespace std;
using namespace cv;
void detect(Mat img, String strCamera) {
    string cascadeName1 = "C:\\ocv3.2\\Build\\install\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";
    CascadeClassifier facedetect;
    bool loaded1 = facedetect.load(cascadeName1);
    Mat original;
    img.copyTo(original);
    vector<Rect> human;
    cvtColor(img, img, CV_BGR2GRAY);
    equalizeHist(img, img);
    facedetect.detectMultiScale(img, human, 1.1, 2, 0 | 1, Size(40, 80), Size(400, 480));
    if (human.size() > 0)
    {
        for (int gg = 0; gg < human.size(); gg++)
        {
            rectangle(original, human[gg].tl(), human[gg].br(), Scalar(0, 0, 255), 2, 8, 0);
        }
    }
    imshow("Detect " + strCamera, original);
    int key6 = waitKey(40);
    //End of the detect
}
void stream(String strCamera) {
    VideoCapture cap(strCamera);
    if (cap.isOpened()) {
        while (true) {
            Mat frame;
            cap >> frame;
            resize(frame, frame, Size(640, 480));
            detect(frame, strCamera);
        }
    }
}
int main() {
    thread cam1(stream, "rtsp://admin:password@ipaddress:554/live2.sdp?tcp");
    thread cam2(stream, "rtsp://admin:password@ipaddress/live2.sdp?tcp");
    cam1.join();
    cam2.join();
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我有类似的问题,并且能够通过完全隔离帧捕获和处理图像来解决它们。我还将OpenCV更新到最新版本(3.2.0),但我认为这也将解决早期版本的问题。

void StreamLoop(String strCamera, LFQueue1P1C<Mat> *imageQueue, bool *shutdown) {
    VideoCapture cap(strCamera, CV_CAP_FFMPEG);
    Mat image;

    while(!(*shutdown) && cap.isOpened()){
        *cap >> image;
        imageQueue->Produce(image);
    }

}

int main(){
    Mat aImage1;
    bool shutdown(false);
    LFQueue1P1C<Mat> imageQueue;
    string rstp("rtsp://admin:password@ipaddress:554/live2.sdp?tcp");
    thread streamThread(StreamLoop, rtsp, &imageQueue, &shutdown);

...

    while(!shutdownCondition){
        if(imageQueue.Consume(aImage1)) {
            // Process Image
            resize(aImage1, aImage1, Size(640, 480));
            detect(aImage1, rtsp);
        }
    }

    shutdown = true;
    if(streamThread.joinable()) streamThread.join();

...
    return 0;
}

似乎OpenCV中的rtsp存在一些问题,如果在拾取帧时甚至有轻微的暂停,它很容易挂起。只要我没有太多停顿就拿起框架,我没有看到任何问题。

另外,当我直接连接到本地网络的摄像机时,我没有遇到此问题。直到我们在一个远程站点部署它们,我才开始进行挂机。将帧检索和处理分离成单独的线程解决了我的问题,希望其他人可能会发现这个解决方案很有用。

注意:我使用的队列是一个自定义队列,用于将项目从一个线程传递到另一个线程。我发布的代码是根据原始代码修改的,以使其更具可读性并适用于此问题。

  

我仍然是多线程问题的初学者,所以任何帮助都会受到赞赏

拥有无法退出的线程将导致您将来出现问题。即使它是测试代码,也要养成确保代码具有退出路径的习惯。举个例子:您可以稍后复制并粘贴一段代码,并忘记那里有一个无限循环,这将导致非常悲痛,以后会尝试追踪您为什么会发生神秘崩溃或者您的资源被锁定。

答案 1 :(得分:0)

我不是C ++开发人员,但是我在Java中也遇到了同样的问题。我通过在阅读相机镜框之前调用VideoCapture.grab()功能解决了我的问题。根据OpenCV Doc,抓取功能的用法是:

  

该功能的主要用途是在多相机环境中,   尤其是当相机没有硬件同步时。

此外,在Java应用程序中,每次读取新框架时都应释放框架的Mat对象。