[OpenCV] Connected Component


/ Published in: C++
Save to your folder(s)



Copy this code and paste it in your HTML
  1. void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
  2. int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
  3. {
  4. /*
  5.   * Pre : "src" is the input image
  6.   * "poly_hull0" smooth method, is usually set to 1
  7.   * "perimScale" defines how big connected component will be retained, bigger
  8.   * the number, more components are retained (100)
  9.   * Post: "num" a in-out value, in for max number of component will be found, out for found components
  10.   * "rects" a in-out value, in is a empty vector, out are the bounding box of components
  11.   * "centers" a in-out value, in is a empty vector, out are the centers of components
  12.   */
  13.  
  14. CvMemStorage* mem_storage = NULL;
  15. CvSeq* contours = NULL;
  16.  
  17.  
  18. // Clean up
  19. cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
  20. cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
  21.  
  22.  
  23. // Find contours around only bigger regions
  24. mem_storage = cvCreateMemStorage(0);
  25.  
  26. CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
  27. CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
  28. CvSeq* c;
  29. int numCont = 0;
  30.  
  31. while ((c = cvFindNextContour(scanner)) != NULL) {
  32.  
  33. double len = cvContourPerimeter(c);
  34.  
  35. // calculate perimeter len threshold
  36. double q = (double)(src->height + src->width)/perimScale;
  37.  
  38. // get rid of blob if its perimeter is too small
  39. if (len < q) {
  40. cvSubstituteContour(scanner, NULL);
  41. } else {
  42.  
  43. // smooth its edge if its large enough
  44. CvSeq* c_new;
  45. if (poly_hull0) {
  46.  
  47. // polygonal approximation
  48. c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
  49.  
  50. } else {
  51.  
  52. // convex hull of the segmentation
  53. c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
  54.  
  55. }
  56.  
  57. cvSubstituteContour(scanner, c_new);
  58.  
  59. numCont++;
  60. }
  61. }
  62.  
  63. contours = cvEndFindContours(&scanner);
  64.  
  65.  
  66. // Calc center of mass and/or bounding rectangles
  67. if (num != NULL) {
  68.  
  69. // user wants to collect statistics
  70. int numFilled = 0, i = 0;
  71.  
  72. for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
  73.  
  74. if (i < *num) {
  75.  
  76. // bounding retangles around blobs
  77.  
  78. rects.push_back( cvBoundingRect(c) );
  79.  
  80. CvPoint center = cvPoint(rects[i].x + rects[i].width / 2,
  81. rects[i].y + rects[i].height / 2);
  82. centers.push_back(center);
  83.  
  84. numFilled++;
  85. }
  86. }
  87.  
  88. *num = numFilled;
  89.  
  90. }
  91.  
  92. cvReleaseMemStorage(&mem_storage);
  93.  
  94. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.