count the number of distinct object in a video

asked 2015-08-13 04:17:24 -0600

breizher gravatar image

updated 2017-08-22 08:43:31 -0600

Hi, I have a video containig object moving with different speed. I would like to count how many object cross a line. For now I am able to track every object in a frame and I write the center of every object on the frame. My first attempt to count these objects was to compare the coordinate of every object with the coordinate of the line (for example my line is horizontal so I compare the Y coordinate). But some object are moving too fast and in the first frame their Y coordinate is less than the Y coordinate of the line and in the next frame it's more. So I decided to extend the counting area (20 pixels) but now I am counting some object twice...

Here is my code :

//update the background model
pMOG2->apply(frame, fgMaskMOG2);

    ///////////////////////////////////////////////////////////////////  
    //morphology element  
    Mat element = getStructuringElement(MORPH_RECT, Size(7, 7), Point(3, 3));
    //pre procesing  
    //1 point delete   
    morphologyEx(fgMaskMOG2, fgMaskMOG2, CV_MOP_CLOSE, element);

    //Find contour  
    ContourImg = fgMaskMOG2.clone();
    //less blob delete  
    vector< vector< Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(ContourImg,
        contours, hierarchy, // a vector of contours  
        CV_RETR_EXTERNAL, // retrieve the external contours  
        CV_CHAIN_APPROX_NONE); // all pixels of each contours  

    /// Get the moments
    vector<Moments> mu(contours.size());
    vector<Point> mc(contours.size());
    vector<Rect> mr(contours.size());   
    /// Draw mass center and contours
    for (int i = 0; i< contours.size(); i++)
    {
        mu[i] = moments(contours[i], false);

        if (contourArea(contours[i], false) > 200){
            mc[i] = Point(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
            mr[i] = boundingRect(contours[i]);
            drawContours(frame, contours, i, CV_RGB(255, 0, 0), 1, 8, hierarchy, 0, Point());
            rectangle(frame, mr[i], CV_RGB(255, 0, 0));
            circle(frame, mc[i], 4, CV_RGB(255, 0, 0), -1, 8, 0);
            if (mc[i].y > 190 && mc[i].y < 210){
                detectedObj = detectedObj + 1;
            }
        }
    }

Maybe the way I am trying to do it is not the best.

How can I manage to count the object crossing a line or an area without missing some or counting twice the same? Thx

edit retag flag offensive close merge delete

Comments

you just need to keep track of the center point of the object in its current and previous positions/coordinates. I think that it is quite simple as an idea and some pseudo code could be:

if (obj_current_center_point > threshold_position && obj_previous_center_point <= threshold_position)
     detectObj++;
else
     skip;

if you want to implement the above for an area, then the checks are becoming a bit more complex but the concept is the same.

theodore gravatar imagetheodore ( 2015-08-13 05:28:35 -0600 )edit

This is exactly what I want to do. For example in a frame I detect 2 objects and I give them an ID : Obj_1 and Obj_2 Then in the next frame I detect 3 objects. How can I keep the good ID of Obj_1 and Obj_2 ? And Give an ID to the new one ?

breizher gravatar imagebreizher ( 2015-08-13 08:48:08 -0600 )edit

so your problem is related to tracking and data association algorithm. For that you will need to search for the kalman filter (tracking) and the hungarian/munskres algorithm (data association algorithm). Have a look in this video the source code is provided as well.

theodore gravatar imagetheodore ( 2015-08-13 11:06:23 -0600 )edit