Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find straight lines in contour openCV

I'm using android openCV and I want to detect triangle, rectangle and circle in an image. So I do it as follow: Canny => findContours => approxPolyDP and get this image: Image Hosted by ImageShack.us


However, the result of approxPolyDP contains so many vertices so I can't determine which shape is it. To eliminate the vertices, I want to detect lines in each contours and find their intersections. How can I do that for a single contour?

like image 424
quacker Avatar asked Jan 14 '13 16:01

quacker


People also ask

How do you find the contour area in OpenCV?

It is found by the function cv. Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and height.


1 Answers

For circles detection, use HoughCircles.

Then here you are just looking for simplified polygons (triangles and squares). Have you tried tweaking epsilon in approxPolyDP?

Here is an example snippet from the openCV squares.cpp sample code - see how approximation accuracy (epsilon, the third parameter of approxPolyDP), is set relative to the size of the contour.

C++ code, but the openCV interface should be the same, so I'm sure it's straightforward to adapt to your environment.

 // test each contour
  for( size_t i = 0; i < contours.size(); i++ )
      {
          // approximate contour with accuracy proportional
          // to the contour perimeter
      approxPolyDP(Mat(contours[i]), approx, 
                        arcLength(Mat(contours[i]), true)*0.02, true);

          // square contours should have 4 vertices after approximation
          // relatively large area (to filter out noisy contours)
          // and be convex.
          // Note: absolute value of an area is used because
          // area may be positive or negative - in accordance with the
          // contour orientation
      if( approx.size() == 4 &&
         fabs(contourArea(Mat(approx))) > 1000 &&
         isContourConvex(Mat(approx)) )
          {
          double maxCosine = 0;

          for( int j = 2; j < 5; j++ )
              {
                  // find the maximum cosine of the angle between joint edges
              double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
              maxCosine = MAX(maxCosine, cosine);
              }

              // if cosines of all angles are small
              // (all angles are ~90 degree) then write quandrange
              // vertices to resultant sequence

          if( maxCosine < 0.3 )
              squares.push_back(approx);
          }
      }
like image 198
foundry Avatar answered Oct 10 '22 19:10

foundry