-1

I am doing a project in OpenCV on estimating the speed of moving vehicle using the video captured. Here the camera is stationary. I have estimated the speed of single object using centroid and Euclidean distance. Now the problem is, I am not getting how to do the same for multiple objects. Here, I need to calculate the Euclidean distance of objects between 2 subsequent frames. I am grateful if anyone would help.

I have created the class-

class centroids
{
    public:
        vector<Point2f> ce;
        vector<float> area;
};
centroids c[100];

And this is the code I've written. I would be grateful if anyone helped me with the code:

findContours( fgMaskMOG2, 
              contours, 
              hierarchy,
              CV_RETR_CCOMP, 
              CV_CHAIN_APPROX_SIMPLE );
int morph_size = 6;
Mat element = getStructuringElement( MORPH_RECT, 
                                     Size( 2*morph_size+1, 2*morph_size+1 ), 
                                     Point( morph_size, morph_size ) );



Scalar color( 255, 255, 255 );  // color of the contour in the
//Draw the contour and rectangle
for( int i = 0; i < contours.size(); i++ )
{
    drawContours( fgMaskMOG2,
                  contours,
                  i, 
                  color, 
                  CV_FILLED,
                  8,
                  hierarchy );
}

//imshow("morpho window",dst);

vector<Moments> mu( contours.size() );

vector<Point2f> mc( contours.size() );
vector<Point2f> m ;

vector<double> time;
vector<Point2f> centroid( mc.size() );

//vector< vector<Point> >::iterator itc = contours.begin();
// iterate through each contour.
double time1[1000];

for( int i = 0; i < contours.size(); i++ )
{
    //  Find the area of contour
    double a = contourArea( contours[i], false ); 

    if( a > 500 )
    {
        mu[i] = moments( contours[i], false );
        mc[i] = Point2f( (mu[i].m10 / mu[i].m00), (mu[i].m01 / mu[i].m00) );
        m.push_back( mc[i] );
        Point2f diff;
        double euclidian = 0;
        for( int f = 0; f < m.size(); f++ )
        {
            if( k == 1 )
            {
                c[f].ce.push_back( m[f] );
                cout << "cen" << c[f].ce << endl;
                euclidian = 0;

            }
            else
            {
                c[f+1].ce.push_back( m[f] );
                cout << "cent" << c[f+1].ce << endl;

                diff = c[f].ce[f] - c[f-1].ce[f-1];

                euclidian = abs( sqrt( (diff.x*diff.x) + (diff.y*diff.y) ) );
                cout << "euclidian" << euclidian << endl;
            }
        }
        cout << "\n centroid" << m << endl;

        circle( fgMaskMOG2, 
                mc[i], 
                5, 
                Scalar( 0, 0, 255 ), 
                1,
                8,
                0 );
    }
}

Thanks in advance :)

callyalater
  • 3,102
  • 8
  • 20
  • 27
dsm
  • 1
  • 3
  • if they are moving horizontally(or whatever) But in the same distance away from the camera (eventually it's the case because you don't have stereo vision) then calculate contour areaa and best fit means same object – Khalil Khalaf Apr 05 '16 at 14:00
  • You will need to figure out an algorithm to track the individual vehicles between consecutive frames (i.e. find the pairs that correspond to the the same object). For inspiration, you can look at what I did in [this question](http://stackoverflow.com/questions/36254452/counting-cars-opencv-python-issue/36274515#36274515) – Dan Mašek Apr 05 '16 at 18:41

1 Answers1

0

You can estimate speed of a moving vehicle based on the video frames only if approximate distance between vehicle and camera is constant throughout the calculation i.e. vehicle is moving in a straight line perpendicular to the camera's vision. So, if camera is looking from side, all the vehicles will be at different distance and calculation will become highly inaccurate for multiple vehicles. Even the vehicles will overlap and their segmentation will be difficult.

There are two scenarios in which your calculation may work -

  1. First, when the camera is capturing from top looking vertically down on vehicles. In this case, there will be a stark difference between the vehicle color and road color. You can use several ways to segment out those individual vehicles, tag them based on their features and identify those vehicles in next frame using the features. This way you'll get position of individual vehicles and then you can predict the speed based on your algorithm. These are following links which will be helpful for segmenting the vechicles -

How to define the markers for Watershed in OpenCV?

http://www.codeproject.com/Articles/751744/Image-Segmentation-using-Unsupervised-Watershed-Al

http://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_Image_Watershed_Algorithm_Marker_Based_Segmentation.php

  1. Second, when vehicles are moving in a single line behind one another. In this case, you can use a combination of color and contour based segmentation depending on the background of your vehicles. After segmentation you can again use object features to identify the position of objects in the next frame. Then run your algorithm for both cases.

If you have complete video sequence of the vehicles, you can segment out different vehicles in the first frame automatically or identify them manually, and then apply motion tracking on those identified objects. You can use Opencv's motion analysis functions and object tracking functions to do so. Thus you'll get position of all tracked vehicles in each frame. So you can easily run and test your speed calculating algorithms.

Community
  • 1
  • 1
Gaurav Raj
  • 699
  • 6
  • 21