Ask Your Question

Intersection of a contour and line in OpenCV c++?

asked 2016-02-27 07:47:06 -0500

sam001 gravatar image

updated 2016-02-27 10:04:50 -0500

LBerger gravatar image

Hi, I am trying to count the number of cars that passes through a line in opencv c++. I have drawn a line on my frame at a specific point and my idea is every time , a car passes through the line, the count variable will be incremented by 1. So, this is what i did.

Step1:- I created an image of zeros with the contour detected in the image.

Step2: - Then i created another image of zeros with just the line this time.

Step3:- Then i took the bitwise AND between these two image and i get the common pixel intersection between these two images.

Step4:- My idea was now if the pixel value in the new image is greater than 0 then i increment the count variable by 1.

So, if i do these then i get a huge value of count. This seems absurd and i would like to know how i correct the error. This is my code so far. Please help me out.

Mat drawing1 = Mat::zeros(resize_blur_Img.size(), CV_8UC1 );
Mat drawing2 = Mat::zeros(resize_blur_Img.size(),CV_8UC1);
Mat res;

for( int i = 0; i < contours.size(); i++ )
     mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );

     drawContours( drawing1, contours, i, Scalar(255,0,0), 2, 8, hierarchy, 0, Point() );

  for(int i =0 ;i <res.rows;i++)
     for(int j=0; j<res.cols;j++)

       if(<uchar>(i,j) > 0)
           found = true;
           count ++;


           found = false;
          // cout<<found<<endl;


edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2016-02-27 10:02:30 -0500

LBerger gravatar image

updated 2016-02-27 14:30:24 -0500

I think you can use lineiterator (may be there is another way to count car)

for (int i=0;i <contour.size();i++)
      drawContours( drawing1, contours, i, Scalar(i+1), 1 ); // contour.size() must be less than 254
cv::LineIterator it(drawing1, Point(0,10),Point(600,300), 4);
cv::LineIterator it2 = it;
vector <int> carCounter(contours.size()); // 

for (int i=0;i <carCounter.size();i++)
for(int nbPt = 0; nbPt < it.count; nbPt++, ++it)
    if (<uchar>(it.pos()) != 0)
int nbCar=0;
for (int i=0;i<carCounter.size();i++)
     if (carCounter[i]!=0)
cout<<nbCar << "cross line\n";

in carCounter number nonzero values is equal to number of car which shapes crossed the red line...

PS I haven't check this program

edit flag offensive delete link more


@Lberger- Thanks a lot for your reply. But this is what its happening so far. The carCounter vector gives me the total number of cars in the frame rather than the number of cars passing through the line. How do i fix it?

sam001 gravatar imagesam001 ( 2016-02-27 14:02:32 -0500 )edit

answered 2016-02-27 22:24:36 -0500

Guyygarty gravatar image

Your life may be easier if the line corresponded to a row of the image. That way you just do:

drawContours( drawing1, contours, i, Scalar(255,0,0), -2, 8, hierarchy, 0, Point() );//note that thickness is negative - that fills the contour.
if (countNonZero(Drawing1.row(300))>0)
//car #i is crossing row 300

The problem with this type of algorithm is that you would need to keep track that you don't count the same car in the next frame.

If only one car at a time can cross the line, you would just need some sort of flag that only allows the counter to increment if there weren't any lit pixels on the line in the previous frame. If multiple cars can cross the line simultaneously, you will need to correlate between car i in one frame and car j in the other. This is much harder

If the cars are relatively slow you could just look at the blob centroids and find the nearest one in the previous frame or maybe one that has moved in a predefined direction. If they are fast (i.e. motion between frames is larger than average distance between cars) you may need a more complex algorithm.


edit flag offensive delete link more

Question Tools

1 follower


Asked: 2016-02-27 07:47:06 -0500

Seen: 6,255 times

Last updated: Feb 27 '16