使用opencv编写的删除面积过小的轮廓的函数

最下面的代码是我未毕业的时候写的,没有错,但是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;
}


从下面的效果图可以看到小的轮廓没有被绿线框住,基本上符合我的想法。我通过一个死循环来检验有无内存泄露,发现内存使用量基本上不增长。我想应该没有内存泄露吧,大牛们还请多指点这个程序有什么错误啊。小弟谢谢啦。


使用opencv编写的删除面积过小的轮廓的函数_第1张图片

你可能感兴趣的:(使用opencv编写的删除面积过小的轮廓的函数)