/ Published in: C++
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
void connectComponent(IplImage* src, const int poly_hull0, const float perimScale, int* num, vector<CvRect> &rects, vector<CvPoint> ¢ers) { /* * 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); }