6

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?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
quacker
  • 336
  • 4
  • 15
  • do the red circles also count as circles? I am asking this coz they have open contours that's why and hence ideally don't qualify as circles... – rotating_image Jan 14 '13 at 16:35
  • The "red circles" are actually the C letter :), I draw it using Core.putText, we don't have to worry about it. – quacker Jan 14 '13 at 16:49

1 Answers1

4

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);
          }
      }
foundry
  • 31,615
  • 9
  • 90
  • 125
  • 1
    There are better ways to detect circles than to use HoughCircles. Check these http://stackoverflow.com/q/4785419/1085483 and http://stackoverflow.com/q/10982988/1085483 – Rui Marques Feb 14 '13 at 12:46