Ask Your Question
0

Ideal motion/object tracking method - Problems with image noise

asked 2013-08-14 11:36:55 -0600

khansen gravatar image

updated 2013-09-04 12:08:39 -0600

Hi all,

I would like to get an idea of the best way to go about tracking people with an ceiling-mounted IP camera. Ultimately, I would like to have an application that does the following:

  • show the video feed in a primary window
  • identifies moving objects then assigns them with an identifier of some kind (object1, object2, etc.)
  • in the primary window, draw a rectangle around each object and add the object ID to it as a tag
  • capture the x and y coordinates of the object or rectangle, preferably the center (it seems that this can be done using the moments() method)
  • in a second window show a binary image of blobs/people in black and everything else in white
  • on the binary image, draw a line from the previous x,y coordinates of each object to the current coordinates

EDIT: I am currently getting far too much noise in my binary image, and have not been able to limit it with the filters I'm using. I'm also unable to track and tag multiple objects. This may be the result of the example I borrowed from, in which only the object with the largest area is tagged. Unfortunately, I have not been able to fix this.

main.cpp - full code found in this Gist

int main(int argc, char *argv[])
{
    // get cam feed and show in new window
    VideoCapture cap(0);
     if (!cap.isOpened())  // if not success, exit program
    {
         cout << "Cannot open the video file" << endl;
         return -1;
    }

    setwindowSettings();   // create window with trackers that adjust filter settings

    // background subtraction init
    BackgroundSubtractorMOG2 bg = BackgroundSubtractorMOG2(hist,thresh,false);

    cap.read(curVid);

    Sleep(5000);

    // show images in windows
    while(1)
    {
        // show camera feed
        bool bSuccess = cap.read(curVid); // read a new frame from video
        if (!bSuccess) // if not success, break loop
        {
            cout << "Cannot read a frame from video file" << endl;
            break;
        }

        // start morph functions then draw
        HSV();                             // apply cvtColor(curVid,imgHSV,CV_BGR2HSV);
        Erosion( 0, 0 );                   // choose erosion type and apply erode(imgHSV,erosion_dst,element); 
        Dilation( 0, 0 );                  // choose dilation type and apply dilate(erosion_dst,dilation_dst,element);

        // background subtraction
            bg(dilation_dst,mask,-1);
        imshow("mask",mask);

        // find and draw contours to Mat test
        trackFilteredObject();
        imshow("test", test);

        // escape program with keystroke
        if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
        {
            cout << "esc key is pressed by user" << endl;
            break; 
        }

    }
    return 0;
}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
3

answered 2013-08-15 21:27:10 -0600

If you want to detect people, look at the people detector of HOGdescriptor (This is the GPU version, but it's almost the same). Look at the sample cpp/peopledetect.cpp to see a full implementation. The sample is drawing box around detected people, and to find the center of that box it's really basic math... no need to use a moment. You could used the moment if you have subtract the background, find the people (in color image, not in foreground) and apply the foreground as a mask of pixel around your detection to have the center of mass of the person, but I'm not sure it's useful.

For the tracking, ie keep the same label for people across time, you could use the Kalman filter, and the sample in cpp/kalman.cpp. More complex approach could involve the blobdetector. The blobdetector is working like other features detector (see tutorial here). It could be a second stage after people detection.

I'm not sure you should use a background subtraction, especially if your camera is moving (PTZ camera for example).

edit flag offensive delete link more

Comments

Thanks for the advice! I'll look into these and post results.

The camera won't be moving at all. It has PTZ functionality, but I only got it for the 360 deg. FOV via fisheye lens. The space it will be in has no windows, so I thought a background subtraction setup using one original image subtracting from the current frame would work quite well. Would you concur? I will be sure to play with HOGdescriptor too. I didn't see the cpp sample you mentioned via the link. Is it somewhere else?

RE to tracking: I don't need to persistently track and ID people after they've left the FOV. It might be nice to have down the road though. What I'm really looking for in these regards is the ability to track many people as they appear in the FOV, at one time then ID ...(more)

khansen gravatar imagekhansen ( 2013-08-16 11:51:24 -0600 )edit

Hi Mathieu. I'm trying PeopleDetect.cpp now, but the softcascade.hpp file doesn't exist within any of the folders in OpenCV 2.4.6. I was able to find it in the 2.9.0.0 documentation, but I don't think that helps me much. Is this a third part library? If so, where can I download it?

khansen gravatar imagekhansen ( 2013-08-27 15:12:46 -0600 )edit

Actually he doesn't refer to the softcascade, which is in fact a delicate version of the cascade classifier algorithm which you can find over here. Also the traincascade files are under the apps folder.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-09-04 01:32:44 -0600 )edit

Question Tools

Stats

Asked: 2013-08-14 11:36:55 -0600

Seen: 3,153 times

Last updated: Sep 04 '13