/refs/circlesCountours.c

https://bitbucket.org/leandromattioli/monnaie · C · 73 lines · 45 code · 7 blank · 21 comment · 7 complexity · 8d13586dcb226493fa79703889879dd6 MD5 · raw file

  1. #include <stdio.h>
  2. #ifndef M_PI
  3. #define M_PI 3.14159265358979323846
  4. #endif
  5. //
  6. // We need this to be high enough to get rid of things that are too small too
  7. // have a definite shape. Otherwise, they will end up as ellipse false positives.
  8. //
  9. #define MIN_AREA 100.00
  10. //
  11. // One way to tell if an object is an ellipse is to look at the relationship
  12. // of its area to its dimensions. If its actual occupied area can be estimated
  13. // using the well-known area formula Area = PI*A*B, then it has a good chance of
  14. // being an ellipse.
  15. //
  16. // This value is the maximum permissible error between actual and estimated area.
  17. //
  18. #define MAX_TOL 100.00
  19. int main( int argc, char** argv )
  20. {
  21. IplImage* src;
  22. // the first command line parameter must be file name of binary (black-n-white) image
  23. if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
  24. {
  25. IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
  26. CvMemStorage* storage = cvCreateMemStorage(0);
  27. CvSeq* contour = 0;
  28. cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
  29. //
  30. // Invert the image such that white is foreground, black is background.
  31. // Dilate to get rid of noise.
  32. //
  33. cvXorS(src, cvScalar(255, 0, 0, 0), src, NULL);
  34. cvDilate(src, src, NULL, 2);
  35. cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
  36. cvZero( dst );
  37. for( ; contour != 0; contour = contour->h_next )
  38. {
  39. double actual_area = fabs(cvContourArea(contour, CV_WHOLE_SEQ, 0));
  40. if (actual_area < MIN_AREA)
  41. continue;
  42. //
  43. // FIXME:
  44. // Assuming the axes of the ellipse are vertical/perpendicular.
  45. //
  46. CvRect rect = ((CvContour *)contour)->rect;
  47. int A = rect.width / 2;
  48. int B = rect.height / 2;
  49. double estimated_area = M_PI * A * B;
  50. double error = fabs(actual_area - estimated_area);
  51. if (error > MAX_TOL)
  52. continue;
  53. printf
  54. (
  55. "center x: %d y: %d A: %d B: %d\n",
  56. rect.x + A,
  57. rect.y + B,
  58. A,
  59. B
  60. );
  61. CvScalar color = CV_RGB( rand() % 255, rand() % 255, rand() % 255 );
  62. cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8, cvPoint(0,0));
  63. }
  64. cvSaveImage("coins.png", dst, 0);
  65. }
  66. }