backgroundSubtraction on multiple frames with OpenMP ( slow performance )

asked 2015-08-17 23:11:38 -0500

Nbb gravatar image

Hi forum,

Im quite new to OpenMP and im having a simple problem. On the program posted below, I did background subtraction.

int main()
{
    capture.open("Vid.mp4");

    MOG2 = createBackgroundSubtractorMOG2();
    MOG2->setShadowValue(0);

    while (1)
    {
        frameNo++;
        capture.read(frame);

        // Frame is 960 x 540
        resize(frame, frame, Size(), 0.5, 0.5, CV_INTER_LINEAR);

        // Display is 960 x 540 
        frame.copyTo(display);

        // Background subtraction on frame
        MOG2->apply(frame, MOGoutput);

        cv::erode(MOGoutput, MOGoutput, getStructuringElement(MORPH_RECT, Size(3, 3)));
        cv::dilate(MOGoutput, MOGoutput, getStructuringElement(MORPH_RECT, Size(3, 3)));

        namedWindow(windowA, CV_WINDOW_NORMAL);
        cv::imshow(windowA, display);

        cv::waitKey(1);
    }
}

In this next program, I used multi-processing to background subtract 2 frames ( from 2 different videos ) in parallel. Note that NO_OF_CAMERAS = 2 and I have removed some functions.

int main()
{

    /****************************************************************************************
    ************************************* INITIALIZE ****************************************
    *****************************************************************************************/

    Ptr<BackgroundSubtractorMOG2> MOG2;;

    VideoCapture         capture[NO_OF_CAMERAS];
    Mat                  frame[NO_OF_CAMERAS], display[NO_OF_CAMERAS];
    string               Camera_Name[NO_OF_CAMERAS] = { "VidA", "VidB" };

    vector<Ball> Ball_Candidates;
    vector<Player> Players;

    omp_set_num_threads(NO_OF_CAMERAS);

    capture[0].open("VidA.avi");
    capture[1].open("VidB.avi");

    FileStorage fs("Cam3_Homography.yml", FileStorage::READ);
    vector<Mat> Homography_Matrix(2);
    fs["Cam3_Homography"] >> Homography_Matrix[0];
    fs.release();

    MOG2 = createBackgroundSubtractorMOG2();
    MOG2->setShadowValue(0);

    while (1)
    {
        #pragma omp parallel private (Ball_Candidates, Players)
        {
            int TID = omp_get_thread_num();
            vector<vector<Point>> MOGcontours;

            capture[TID].read(frame[TID]);
            if (frame[TID].empty()) { exit(0); }

            resize(frame[TID], frame[TID], Size(), 0.5, 0.5, CV_INTER_LINEAR);
            frame[TID].copyTo(display[TID]);

            MOG2->apply(frame[TID], frame[TID]);
            erode(frame[TID], frame[TID], getStructuringElement(MORPH_RECT, Size(3, 3)));
            dilate(frame[TID], frame[TID], getStructuringElement(MORPH_RECT, Size(3, 3)));

            namedWindow(Camera_Name[TID], CV_WINDOW_AUTOSIZE);
            imshow(Camera_Name[TID], display[TID]);
            waitKey(1);

            //#pragma omp barrier
        }


    }
}

The frame rate is much slower for the program running on 2 threads. Did I wrongly initialize the parallel threads ? Maybe I should put the #omp parallel private outside the while loop ? Im still reading up on the tutorials for OpenMP so im still new. I hope I can get some advice on this.

Thanks

edit retag flag offensive close merge delete

Comments

I see two problems in your code. First you are using openmp thread outside of opencv. Opencv use many thread in erode or dilate.You think you've got two threads but I don't think that opencv knows that there is already two threads. As efficiency is approximatively thread number equal to core numbers it could be a problem.

Second problem there is bottle neck in your code it's hard disk reading. May be reading is 50% time cpu. That's difficult to improve.

LBerger gravatar imageLBerger ( 2015-08-18 01:06:21 -0500 )edit

Okay thanks. I guess I shall just continue my work while I read up on how I can optimize my code when multi-processing with opencv.

Nbb gravatar imageNbb ( 2015-08-18 02:25:58 -0500 )edit