Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lag in opencv videocapture when i use rtsp camera stream

So i'm currently working on a project that needs to do a facial recognition on rtsp ip cam , i managed to get the rtsp feed with no problems, but when it comes to applying the face recognition the video feed gets too slow and shows a great delay, i even used multithreading to make it better but with no success,here is my code i'm still a beginner in multi threading matters so any help would be appreciated.

    #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;
}
like image 305
deepmore Avatar asked Mar 13 '17 10:03

deepmore


2 Answers

I had similar issues and was able to resolve them by completely isolating the frame capturing from processing of the images. I also updated OpenCV to the latest (3.2.0) available, but I think this will also resolve problems with earlier versions.

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

It seems that there is some issue with rtsp in OpenCV where it easily hangs up if there are even slight pauses while picking up the frames. As long as I pick up frames without much pause I have not seen a problem.

Also, I didn't have this issue when the video cameras where directly connected to my local network. It was not until we deployed them at a remote site that I started getting the hang ups. Separating frame retrieval and processing into separate threads resolved my issues, hopefully someone else might find this solution useful.

Note: The queue I used is a custom queue for passing items from one thread to another. The code I posted is modified from my original code to make it more readable and applicable to this problem.

i'm still a beginner in multi threading matters so any help would be appreciated

Having threads that have no way of exiting will cause you issues in the future. Even if it is test code, get in the habit of making sure the code has an exit path. As an example: You might copy and paste a section of code later on and forget there is an infinite loop in there and it will cause great grief later trying to track down why you have mysterious crashing or your resources are locked up.

like image 134
Xiver Avatar answered Oct 13 '22 00:10

Xiver


I am not a C++ developer but I had the same problem in Java. I solved my issue by calling VideoCapture.grab() function before reading camera frame. According to OpenCV Doc, the use of the grab function is :

The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization.

Besides that, in java application, you should release your frame's Mat objects every time you read new frames.

like image 26
gigili Avatar answered Oct 12 '22 23:10

gigili