转自: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<Point> &contourlist)
- {
- Mat image_contour_all = src.clone();
- Mat image_contour_outside = src.clone();
-
- vector<vector<Point> > contours_out;
- vector<Vec4i> hierarchy_out;
- findContours(image_contour_outside, contours_out, hierarchy_out, RETR_EXTERNAL, CHAIN_APPROX_NONE);
-
- vector<vector<Point> > contours_all;
- vector<Vec4i> 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;
- }
- }
- }
-
-
-
- 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;
- }
效果如图所示:
这个函数的原理就是:
1、找出所有的轮廓,包含内轮廓和外轮廓;
2、仅找出外轮廓;
3、删除所有轮廓中的外轮廓,即得到内轮廓
4、找出内轮廓中的最大轮廓
这是我目前想到的方法,如果读到这篇博文的读者,有更好的方法和建议,欢迎提出。