最下面的代码是我未毕业的时候写的,没有错,但是Cvseq不能传递到其他函数,在http://www.opencv.org.cn/forum/viewtopic.php?t=8300的代码的帮助下写了如下的代码,下面的代码的执行效率更高。
int Contours::findContours() { this->firstContour = NULL;//全局变量。 numCon = 0;//轮廓的个数 CvContourScanner scanner = cvStartFindContours(this->imgBinary,this->storage);//参看学习opencv CvSeq * seq =NULL; double indexArea; while( (seq = cvFindNextContour(scanner) ) != NULL)//开始查找 { indexArea = fabs(cvContourArea(seq)/(imgBinary->width * imgBinary->height) ); if(indexArea >this->thresholdLow && indexArea <= this->thresholdHigh)//如果寻找出的轮廓的面积大于low,并且小于high,则留下,反之,则删除。 { //符合留下的条件。 numCon = numCon+1; }else { cvSubstituteContour(scanner,NULL);//删除当前的轮廓 } } this->firstContour = cvEndFindContours(&scanner);//把找到的轮廓返回到firstContour中。 return this->numCon; }
int removeNoise(IplImage *img ) { IplImage *img_contour = cvCreateImage(cvGetSize(img),8,1); IplImage *img_contour_3 = cvCreateImage(cvGetSize(img),8,3); cvCopy(img,img_contour); cvCvtColor(img,img_contour_3,CV_GRAY2BGR); CvMemStorage *storage= cvCreateMemStorage(); CvSeq * first_contour = NULL; int Nc = cvFindContours( img_contour, storage, &first_contour, sizeof(CvContour), CV_RETR_LIST ); int num_contours = 0; struct min_max_list *head = NULL; double area = 0; double areaOfImg = img->width *img->height; CvSeq *cPrev = first_contour; CvSeq *cNext = NULL; bool first= true; for(CvSeq *c = first_contour;c!= NULL;c= cNext) { area = fabs(cvContourArea(c) ); if(area <areaOfImg *0.01) { cNext = c->h_next; cvClearSeq(c); //cvClearMemStorage(c->storage);//回收内存 continue; }//if else { if(first) first_contour = c; first = false; cvDrawContours( img_contour_3, c, COLOR_GREEN, COLOR_GREEN, 0, 2, 8); } cNext= c->h_next; }//for first_constours; cvShowImage("removeNoise",img); cvShowImage("33333",img_contour_3); cvWaitKey(); //释放内存。 cvReleaseImage(&img_contour_3); cvReleaseImage(&img_contour); cvReleaseMemStorage(&storage); return 0; }
从下面的效果图可以看到小的轮廓没有被绿线框住,基本上符合我的想法。我通过一个死循环来检验有无内存泄露,发现内存使用量基本上不增长。我想应该没有内存泄露吧,大牛们还请多指点这个程序有什么错误啊。小弟谢谢啦。