Opencv cvFindContours 函数的详细说明

最近做连通域分析
最初想自己写,发现好多东西居然不知道怎么做,比如说怎么找内轮廓等
于是改用cvBlobslib,发现他的架构还是不错的,不过很不爽的,让我发现了几处内存泄露,然后实际得到的轮廓似乎也比真正的轮廓少一圈,此外就是这个命名一塌糊涂,费了我好一段时间才大体搞明白,还是决定放弃

最后没办法,只好用cvFindContours来代替了
cvFindContours(
CvArr* image,
CvMemStorage* storage,
CvSeq** first_contour,
int header_size CV_DEFAULT(sizeof(CvContour)),
int mode CV_DEFAULT(CV_RETR_LIST),
int method CV_DEFAULT(CV_CHAIN_APPROX_SIMPLE),
CvPoint offset CV_DEFAULT(cvPoint(0,0)));
有几个参数意思比较明显,这里就不再多说了
重点解释一下mode ,method这两处

mode 有下面四个
#define CV_RETR_EXTERNAL 0
#define CV_RETR_LIST 1
#define CV_RETR_CCOMP 2
#define CV_RETR_TREE 3
其中External 和觉得就是找外轮廓(如果一个物体内部有空洞的话,很自然的有内轮廓)然后用contour->h_next遍历就行了

CV_RETR_LIST这种形式是不管外轮廓还是内轮廓通通以list的形式存储,这时我们可以用cvContourArea来求轮廓的面积,如果是外轮廓的话,面积应该是负的,反之,面积应该是正的,遍历时也用contour->h_next就行了

CCOMP就是找轮廓的连通域,没有空洞的话,就是只有外轮廓了,有空洞的话,也有内轮廓(他与下面的CV_RETR_TREE 不同的是,CCOMP只包含一层嵌套,也即一个外轮廓只包含一个内轮廓,而CV_RETR_TREE会包含好多层)
用contour->h_next遍历的是外轮廓,在每一个外轮廓里,求一次contour->v_next得到他所包含的内轮廓即可

CV_RETR_TREE 是以树的形式来表示,把内轮廓作为包含他的外轮廓的child,
用contour->h_next遍历的是外轮廓,在每一个外轮廓里,遍历contour->v_next得到他所包含的内轮廓

method
#define CV_CHAIN_CODE 0
#define CV_CHAIN_APPROX_NONE 1
#define CV_CHAIN_APPROX_SIMPLE 2
#define CV_CHAIN_APPROX_TC89_L1 3
#define CV_CHAIN_APPROX_TC89_KCOS 4
#define CV_LINK_RUNS 5
好象主要是轮廓所包含点的存储形式,我就知道
CV_CHINA_CODE和CV_CHIAN_APPROX_SIMPLE两种
一般我们只要用CV_CHIAN_APPROX_SIMPLE就可以了,在这种格式下,貌似轮廓就是以点集的形式来表示。

然后再说一下cvDrawContours
cvDrawContours( CvArr *img, CvSeq* contour,
CvScalar external_color, CvScalar hole_color,
int max_level, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8),
CvPoint offset CV_DEFAULT(cvPoint(0,0)));
其他参数比较好理解
主要说一下max_level
我感觉这个max_level主要还是和轮廓之间的嵌套相关
1 r
0 e e e
-1 i1 i1 i1 i1
-2 i2 i2 i2 i2
-3 i3 i3
最顶层的是root,包含所有的外轮廓,level是1
然后是外轮廓 level是0
然后是外轮廓包含的内轮廓 level是-1
然后是外轮廓包含的内轮廓包含的轮廓 level是-2



cvDrawContours绘制的是(maxlevel)以上的
所有如果maxlevel是1,则一次画完所有的外轮廓
如果maxlevel是0,则只画当前轮廓的外轮廓
如果maxlevel是-1,则绘制当前轮廓的外轮廓及他的下一层子轮廓
依次类推
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值