Return to Snippet

Revision: 31836
at September 15, 2010 00:43 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *       "poly_hull0" smooth method, is usually set to 1
    *       "perimScale" defines how big connected component will be retained, bigger
    *                    the number, more components are retained (100)
    * Post: "num" a in-out value, in for max number of component will be found, out for found components
    *       "rects" a in-out value, in is a empty vector, out are the bounding box of components
    *       "centers" a in-out value, in is a empty vector, out are the centers of components
    */   
 
    CvMemStorage* mem_storage = NULL;
    CvSeq* contours = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    mem_storage = cvCreateMemStorage(0);
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                   CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
 
                rects.push_back( cvBoundingRect(c) );           
 
                CvPoint center = cvPoint(rects[i].x + rects[i].width  / 2,
                    rects[i].y + rects[i].height / 2);
                centers.push_back(center);
 
                numFilled++;
            }
        }
 
        *num = numFilled;       
 
    }   
 
    cvReleaseMemStorage(&mem_storage);
 
}

Revision: 31835
at September 15, 2010 00:42 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *       "poly_hull0" smooth method, is usually set to 1
    *       "perimScale" defines how big connected component will be retained, bigger
    *                    the number, more components are retained (100)
    * Post: "num" a in-out value, in for max number of component will be found, out for  practically found components
    *       "rects" a in-out value, in is a empty vector, out are the bounding box of components
    *       "centers" a in-out value, in is a empty vector, out are the centers of components
    */   
 
    CvMemStorage* mem_storage = NULL;
    CvSeq* contours = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    mem_storage = cvCreateMemStorage(0);
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                   CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
 
                rects.push_back( cvBoundingRect(c) );           
 
                CvPoint center = cvPoint(rects[i].x + rects[i].width  / 2,
                    rects[i].y + rects[i].height / 2);
                centers.push_back(center);
 
                numFilled++;
            }
        }
 
        *num = numFilled;       
 
    }   
 
    cvReleaseMemStorage(&mem_storage);
 
}

Revision: 31834
at September 15, 2010 00:30 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *       "poly_hull0" is usually set to 1
    *       "perimScale" defines how big connected component will be retained, bigger
    *                    the number, more components are retained (100)
    * Post: "num" defines how many connected component was found
    *       "rects" the bounding box of each connected component
    *       "centers" the center of each bounding box
    */    
 
    CvMemStorage* mem_storage = NULL;
    CvSeq* contours = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    mem_storage = cvCreateMemStorage(0);
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                   CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
 
                rects.push_back( cvBoundingRect(c) );           
 
                CvPoint center = cvPoint(rects[i].x + rects[i].width  / 2,
                    rects[i].y + rects[i].height / 2);
                centers.push_back(center);
 
                numFilled++;
            }
        }
 
        *num = numFilled;       
 
    }   
 
    cvReleaseMemStorage(&mem_storage);
 
}

Revision: 31833
at September 15, 2010 00:14 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *       "poly_hull0" is usually set to 1
    *       "perimScale" defines how big connected component will be retained, bigger
    *                    the number, more components are retained (100)
    * Post: "num" defines how many connected component was found
    *       "rects" the bounding box of each connected component
    *       "centers" the center of each bounding box
    */    
 
    CvMemStorage* mem_storage = NULL;
    CvSeq* contours = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    mem_storage = cvCreateMemStorage(0);
 
    /*if (mem_storage == NULL) {
        mem_storage = cvCreateMemStorage(0);
    } else {
        cvClearMemStorage(mem_storage);
    }*/
 
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                   CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
                if (rects.size() != 0) {                   
                    rects[i] = cvBoundingRect(c);
 
                }
 
                if (centers.size() != 0) {
                    centers[i].x = rects[i].x + rects[i].width / 2;
                    centers[i].y = rects[i].y + rects[i].height / 2;
 
                }
 
                numFilled++;
            }
        }
 
        *num = numFilled;       
 
    }   
 
    cvReleaseMemStorage(&mem_storage);
 
    vector<CvRect>::iterator itBegin = rects.begin();
    vector<CvRect>::iterator itEnd   = rects.begin() + (*num);
    rects = vector<CvRect>(itBegin, itEnd);
 
    vector<CvPoint>::iterator itBegin1 = centers.begin();
    vector<CvPoint>::iterator itEnd1   = centers.begin() + (*num);
    centers = vector<CvPoint>(itBegin1, itEnd1);
 
 
}

Revision: 31832
at September 14, 2010 13:00 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *        "poly_hull0" is usually set to 1
    *        "perimScale" defines how big connected component will be retained, bigger
    *        the number, more components are retained (100)
    * Post: "num" defines how many connected component was found
    *        "rects" the bounding box of each connected component
    *        "centers" the center of each bounding box
    */    
 
    static CvMemStorage* mem_storage = NULL;
    static CvSeq* contours = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    if (mem_storage == NULL) {
        mem_storage = cvCreateMemStorage(0);
    } else {
        cvClearMemStorage(mem_storage);
    }
 
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                    CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
 
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
    // Some convenience variables
    const CvScalar CVX_WHITE = CV_RGB(0xff, 0xff, 0xff);
    const CvScalar CVX_BLACK = CV_RGB(0x00, 0x00, 0x00);           
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
                if (rects.size() != 0) {                   
                    rects[i] = cvBoundingRect(c);
 
                }
 
                if (centers.size() != 0) {
                    centers[i].x = rects[i].x + rects[i].width / 2;
                    centers[i].y = rects[i].y + rects[i].height / 2;
 
                }
 
                numFilled++;
            }
        }
 
        *num = numFilled;
 
    }
 
    vector<CvRect>::iterator itBegin = rects.begin();
    vector<CvRect>::iterator itEnd   = rects.begin() + (*num);
    rects = vector<CvRect>(itBegin, itEnd);
 
    vector<CvPoint>::iterator itBegin1 = centers.begin();
    vector<CvPoint>::iterator itEnd1   = centers.begin() + (*num);
    centers = vector<CvPoint>(itBegin1, itEnd1);
 
}

Revision: 31831
at September 14, 2010 12:56 by browny


Updated Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
                      int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
    /*
    * Pre : "src" is the input image
    *       "poly_hull0" is usually set to 1
    *       "perimScale" defines how big connected component will be retained, bigger
    *                    the number, more components are retained (100)
    * Post: "num" defines how many connected component was found
    *       "rects" the bounding box of each connected component
    *       "centers" the center of each bounding box
    */    
 
    static CvMemStorage* mem_storage = NULL;
    static CvSeq*        contours    = NULL;       
 
 
    // Clean up   
    cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
    cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
    // Find contours around only bigger regions
    if (mem_storage == NULL) {
        mem_storage = cvCreateMemStorage(0);
    } else {
        cvClearMemStorage(mem_storage);
    }
 
 
    CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
                                                   CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
 
    CvSeq* c;
    int numCont = 0;
 
    while ((c = cvFindNextContour(scanner)) != NULL) {
 
        double len = cvContourPerimeter(c);
 
        // calculate perimeter len threshold
        double q = (double)(src->height + src->width)/perimScale;
 
        // get rid of blob if its perimeter is too small
        if (len < q) {
            cvSubstituteContour(scanner, NULL);
        } else {
 
            // smooth its edge if its large enough                       
            CvSeq* c_new;
            if (poly_hull0) {
 
                // polygonal approximation
                c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
            } else {
 
                // convex hull of the segmentation
                c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
            }
 
            cvSubstituteContour(scanner, c_new);
 
            numCont++;
        }
    }       
 
    contours = cvEndFindContours(&scanner);
 
    // Some convenience variables
    const CvScalar CVX_WHITE = CV_RGB(0xff, 0xff, 0xff);
    const CvScalar CVX_BLACK = CV_RGB(0x00, 0x00, 0x00);           
 
    // Calc center of mass and/or bounding rectangles
    if (num != NULL) {
 
        // user wants to collect statistics
        int numFilled = 0, i = 0;
 
        for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
            if (i < *num) {
 
                // bounding retangles around blobs               
                if (rects.size() != 0) {                   
                    rects[i] = cvBoundingRect(c);
 
                }
 
                if (centers.size() != 0) {
                    centers[i].x = rects[i].x + rects[i].width / 2;
                    centers[i].y = rects[i].y + rects[i].height / 2;
 
                }
 
                numFilled++;
            }
        }
 
        *num = numFilled;
 
    }
 
    vector<CvRect>::iterator itBegin = rects.begin();
    vector<CvRect>::iterator itEnd   = rects.begin() + (*num);
    rects = vector<CvRect>(itBegin, itEnd);
 
    vector<CvPoint>::iterator itBegin1 = centers.begin();
    vector<CvPoint>::iterator itEnd1   = centers.begin() + (*num);
    centers = vector<CvPoint>(itBegin1, itEnd1);
 
}

Revision: 31830
at September 14, 2010 12:53 by browny


Initial Code
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale,
            int* num, vector<CvRect> &rects, vector<CvPoint> &centers)
{
  /*
  * Pre : "src" is the input image
  *       "poly_hull0" is usually set to 1
  *       "perimScale" defines how big connected component will be retained, bigger
  *                   the number, more components are retained (100)
  * Post: "num" defines how many connected component was found
  *       "rects" the bounding box of each connected component
  *       "centers" the center of each bounding box
  */    
 
  static CvMemStorage* mem_storage = NULL;
  static CvSeq*        contours    = NULL;   
 
 
  // Clean up 
  cvMorphologyEx(src, src, 0, 0, CV_MOP_OPEN, 1);
  cvMorphologyEx(src, src, 0, 0, CV_MOP_CLOSE, 1);
 
 
  // Find contours around only bigger regions
  if (mem_storage == NULL) {
    mem_storage = cvCreateMemStorage(0);
  } else {
    cvClearMemStorage(mem_storage);
  }
 
 
  CvContourScanner scanner = cvStartFindContours(src, mem_storage, sizeof(CvContour),
    CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
  CvSeq* c;
  int numCont = 0;
 
  while ((c = cvFindNextContour(scanner)) != NULL) {
 
    double len = cvContourPerimeter(c);
 
    // calculate perimeter len threshold
    double q = (double)(src->height + src->width)/perimScale;
 
    // get rid of blob if its perimeter is too small
    if (len < q) {
      cvSubstituteContour(scanner, NULL);
    } else {
 
      // smooth its edge if its large enough           
      CvSeq* c_new;
      if (poly_hull0) {
 
        // polygonal approximation
        c_new = cvApproxPoly(c, sizeof(CvContour), mem_storage, CV_POLY_APPROX_DP, 2, 0);
 
      } else {
 
        // convex hull of the segmentation
        c_new = cvConvexHull2(c, mem_storage, CV_CLOCKWISE, 1);
 
      }
 
      cvSubstituteContour(scanner, c_new);
 
      numCont++;
    }
  }   
 
  contours = cvEndFindContours(&scanner);
 
  // Some convenience variables
  const CvScalar CVX_WHITE = CV_RGB(0xff, 0xff, 0xff);
  const CvScalar CVX_BLACK = CV_RGB(0x00, 0x00, 0x00);     
 
  // Calc center of mass and/or bounding rectangles
  if (num != NULL) {
 
    // user wants to collect statistics
    int numFilled = 0, i = 0;
 
    for (i = 0, c = contours; c != NULL; c = c->h_next, i++) {
 
      if (i < *num) {
 
        // bounding retangles around blobs       
        if (rects.size() != 0) {         
          rects[i] = cvBoundingRect(c);
 
        }
 
        if (centers.size() != 0) {
          centers[i].x = rects[i].x + rects[i].width / 2;
          centers[i].y = rects[i].y + rects[i].height / 2;
 
        }
 
        numFilled++;
      }
    }
 
    *num = numFilled;
 
  }
 
  vector<CvRect>::iterator itBegin = rects.begin();
  vector<CvRect>::iterator itEnd   = rects.begin() + (*num);
  rects = vector<CvRect>(itBegin, itEnd);
 
  vector<CvPoint>::iterator itBegin1 = centers.begin();
  vector<CvPoint>::iterator itEnd1   = centers.begin() + (*num);
  centers = vector<CvPoint>(itBegin1, itEnd1);
 
}

Initial URL


Initial Description


Initial Title
[OpenCV] Connected Component

Initial Tags


Initial Language
C++