Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Background subtraction and object counting - slow performance

Hi,

I'm trying to write down a code to count objects that will be moving from left to right in the FoV, so I guess I don't need to track them and I'm just going for a check when the center point of an object gets into a ROI (for example the middle of the image).

I've used background subtraction to easily highlights objects to count, then with findcontours and the center of the bounding rect I get the point that will be used to count every object.

The code seems to work "quite well" if i'm working with very low resolution videos: in this first example ( Video 1 ) I'm counting some pens, but I need to define a pixel range where the rect center could be located to get it counted or the pen will be missed. Also the 6th pen is not being counted.

When I run the code the video is playing slower than it's normal speed. Is it my PC working bad or is it the code bad written? When trying to work with higher resolution video (like this one Video 2 the code isn't giving any result at all, cannot identify almost any rect.

Any suggestion? What am I doing wrong?

Thanks for helping

Here's the source code:

#include < stdio.h>  
#include < stdlib.h>

#include < opencv2\opencv.hpp>  
#include < opencv2/core/core.hpp>  
#include < opencv2/highgui/highgui.hpp>  
#include < opencv2/video/background_segm.hpp> 


using namespace std;
using namespace cv;


// Global variables
Mat img, frame, fgMaskMOG; 
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

Ptr< BackgroundSubtractor> pMOG; //MOG Background subtractor  



static Rect pointSetBoundingRect(const Mat& points, Mat m)
{
    int npoints = points.checkVector(2);


    int  xmin = 0, ymin = 0, xmax = -1, ymax = -1, i;
    Point ptxmin, ptymin, ptxmax, ptymax;

    if (npoints == 0)
        return Rect();

    const Point* pts = points.ptr<Point>();
    Point pt = pts[0];

    ptxmin = ptymin = ptxmax = ptymax = pt;
    xmin = xmax = pt.x;
    ymin = ymax = pt.y;

    for (i = 1; i < npoints; i++)
    {
        pt = pts[i];

        if (xmin > pt.x)
        {
            xmin = pt.x;
            ptxmin = pt;
        }


        if (xmax < pt.x)
        {
            xmax = pt.x;
            ptxmax = pt;
        }

        if (ymin > pt.y)
        {
            ymin = pt.y;
            ptymin = pt;
        }

        if (ymax < pt.y)
        {
            ymax = pt.y;
            ptymax = pt;
        }
    }
    return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
}



int main()
{
    pMOG = new BackgroundSubtractorMOG();

    int Count = 0;

    VideoCapture cap("../4.avi");

    while (true)
    {
        cap >> frame;

        pMOG->operator()(frame, fgMaskMOG);

        findContours(fgMaskMOG, contours, hierarchy, CV_RETR_CCOMP, CHAIN_APPROX_SIMPLE);
        Mat dst = Mat::zeros(frame.rows, frame.cols, CV_8UC3);

        for (size_t i = 0; i < contours.size(); i++)
        {
            Rect minRect = pointSetBoundingRect(Mat(contours[i]), dst);
            if (minRect.area() > 2000)
            {
                rectangle(dst, minRect, Scalar(0, 0, 255), 3, 8);
                Point center = Point((minRect.x + (minRect.width) / 2), (minRect.y + (minRect.height) / 2));
                circle(dst, center, 2, Scalar(255, 0, 0), 2, 8, 0);
                if (center.x > 300 & center.x < 308)
                {
                    Count++;
                }
            }

            char text[30];
            sprintf_s(text, "Bars: %d", Count);
            IplImage iplimg = dst;
            CvFont font;
            double hScale = 1.5;
            double vScale = 1.5;
            int lineWidth = 2;
            cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
            cvPutText(&iplimg, text, cvPoint(30, 50), &font, cvScalar(255, 255, 0));

            cvShowImage("Contours", &iplimg);
        }

        imshow("Origin", frame);
        imshow("MOG", fgMaskMOG);


        if (waitKey(30) >= 0)
            break;

    }


}

Background subtraction and object counting - slow performance

Hi,

I'm trying to write down a code to count objects that will be moving from left to right in the FoV, so I guess think I don't need to track them and I'm just going for a check when the center point of an object gets into a ROI (for example the middle of the image).

I've used background subtraction to easily highlights objects to count, then with findcontours and the center of the bounding rect I get the point that will be used to count every object.

The code seems to work "quite well" if i'm I'm working with very low resolution videos: in this first example ( Video 1 ) I'm counting some pens, but I need to define a pixel range of 8 pixels where the rect center could be located to get it counted or the pen will be missed. Also the 6th pen is not being counted.

When I run the code the video is playing slower than it's normal speed. Is it my PC working bad or is it the code bad written? When trying to work with higher resolution video (like this one Video 2 the code isn't giving any result at all, cannot identify almost any rect.

Any suggestion? What am I doing wrong?

Thanks for helping

Here's the source code:

#include < stdio.h>  
#include < stdlib.h>

#include < opencv2\opencv.hpp>  
#include < opencv2/core/core.hpp>  
#include < opencv2/highgui/highgui.hpp>  
#include < opencv2/video/background_segm.hpp> 


using namespace std;
using namespace cv;


// Global variables
Mat img, frame, fgMaskMOG; 
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

Ptr< BackgroundSubtractor> pMOG; //MOG Background subtractor  



static Rect pointSetBoundingRect(const Mat& points, Mat m)
{
    int npoints = points.checkVector(2);


    int  xmin = 0, ymin = 0, xmax = -1, ymax = -1, i;
    Point ptxmin, ptymin, ptxmax, ptymax;

    if (npoints == 0)
        return Rect();

    const Point* pts = points.ptr<Point>();
    Point pt = pts[0];

    ptxmin = ptymin = ptxmax = ptymax = pt;
    xmin = xmax = pt.x;
    ymin = ymax = pt.y;

    for (i = 1; i < npoints; i++)
    {
        pt = pts[i];

        if (xmin > pt.x)
        {
            xmin = pt.x;
            ptxmin = pt;
        }


        if (xmax < pt.x)
        {
            xmax = pt.x;
            ptxmax = pt;
        }

        if (ymin > pt.y)
        {
            ymin = pt.y;
            ptymin = pt;
        }

        if (ymax < pt.y)
        {
            ymax = pt.y;
            ptymax = pt;
        }
    }
    return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
}



int main()
{
    pMOG = new BackgroundSubtractorMOG();

    int Count = 0;

    VideoCapture cap("../4.avi");

    while (true)
    {
        cap >> frame;

        pMOG->operator()(frame, fgMaskMOG);

        findContours(fgMaskMOG, contours, hierarchy, CV_RETR_CCOMP, CHAIN_APPROX_SIMPLE);
        Mat dst = Mat::zeros(frame.rows, frame.cols, CV_8UC3);

        for (size_t i = 0; i < contours.size(); i++)
        {
            Rect minRect = pointSetBoundingRect(Mat(contours[i]), dst);
            if (minRect.area() > 2000)
            {
                rectangle(dst, minRect, Scalar(0, 0, 255), 3, 8);
                Point center = Point((minRect.x + (minRect.width) / 2), (minRect.y + (minRect.height) / 2));
                circle(dst, center, 2, Scalar(255, 0, 0), 2, 8, 0);
                if (center.x > 300 & center.x < 308)
                {
                    Count++;
                }
            }

            char text[30];
            sprintf_s(text, "Bars: %d", Count);
            IplImage iplimg = dst;
            CvFont font;
            double hScale = 1.5;
            double vScale = 1.5;
            int lineWidth = 2;
            cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
            cvPutText(&iplimg, text, cvPoint(30, 50), &font, cvScalar(255, 255, 0));

            cvShowImage("Contours", &iplimg);
        }

        imshow("Origin", frame);
        imshow("MOG", fgMaskMOG);


        if (waitKey(30) >= 0)
            break;

    }


}