opencv findcontour查找最大的内轮廓

问题是怎么来的呢

       比如输入一幅图像,往往需要我们找最大的轮廓,如果是仅仅是查找最大的轮廓,那么问题也比较简单了,直接找出所有的轮廓,然后根据轮廓的面积,遍历查找出最大的轮廓即可。如果是找最大的外轮廓,那么问题也比较简单,因为findContours(image_contour_outside, contours_out, hierarchy_out, RETR_EXTERNAL, CHAIN_APPROX_NONE);有参数,CV_RETR_EXTERNAL:只检索最外面的轮廓。fingcontours函数详解,可参考百度百科。

现在的问题是:我们要查找最大的内轮廓。如果有一个参数,限定只找内轮廓就好了,可惜opencv并没有提供这样的接口。那么问题就需要我们自己动手解决了。

话不多说,直接上代码吧。开发环境vs2013+opencv2.4.13

int chao_get_pointlist_inner_contour2(Mat src, vector &contourlist)
{
	Mat image_contour_all = src.clone();
	Mat image_contour_outside = src.clone();

	vector > contours_out;
	vector hierarchy_out;
	findContours(image_contour_outside, contours_out, hierarchy_out, RETR_EXTERNAL, CHAIN_APPROX_NONE);

	vector > contours_all;
	vector hierarchy_all;
	findContours(image_contour_all, contours_all, hierarchy_all, RETR_TREE, CHAIN_APPROX_NONE);

	if (contours_all.size() == contours_out.size()) return -1;//没有内轮廓,则提前返回

	for (int i = 0; i < contours_out.size(); i++)
	{
		int conloursize = contours_out[i].size();
		for (int j = 0; j < contours_all.size(); j++)
		{
			int tem_size = contours_all[j].size();
			if (conloursize == tem_size)
			{
				swap(contours_all[j], contours_all[contours_all.size() - 1]);
				contours_all.pop_back();
				break;
			}
		}
	}

	//contours_all中只剩下内轮廓
	//查找最大轮廓
	double maxarea = 0;
	int maxAreaIdx = 0;
	for (int index = contours_all.size() - 1; index >= 0; index--)
	{
		double tmparea = fabs(contourArea(contours_all[index]));
		if (tmparea>maxarea)
		{
			maxarea = tmparea;
			maxAreaIdx = index;//记录最大轮廓的索引号
		}
	}

	contourlist = contours_all[maxAreaIdx];

	return 0;
}

效果如图所示:

opencv findcontour查找最大的内轮廓_第1张图片


这个函数的原理就是:

1、找出所有的轮廓,包含内轮廓和外轮廓;

2、仅找出外轮廓;

3、删除所有轮廓中的外轮廓,即得到内轮廓

4、找出内轮廓中的最大轮廓


这是我目前想到的方法,如果读到这篇博文的读者,有更好的方法和建议,欢迎提出。




你可能感兴趣的:(opencv)