from:http://blog.sina.com.cn/s/blog_4bc179a80100hs50.html
函数cvFindContours从二值图像中检索轮廓,并返回检测到的轮廓的个数。first_contour的值由函数填充返回,它的值将为第一个外轮廓的指针,当没有轮廓被检测到时为NULL。其它轮廓可以使用h_next和v_next连接,从first_contour到达。
int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
intheader_size=sizeof(CvContour), int mode=CV_RETR_LIST,
intmethod=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );
image
8比特单通道的源二值图像。非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny。
storage
返回轮廓的容器。
first_contour
输出参数,用于存储指向第一个外接轮廓。
header_size
header序列的尺寸.如果选择method = CV_CHAIN_CODE, 则header_size >= sizeof(CvChain);其他,则
header_size >= sizeof(CvContour)。
mode
检索模式,可取值如下:
CV_RETR_EXTERNAL:只检索最外面的轮廓;
CV_RETR_LIST:检索所有的轮廓,并将其放入list中;
CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。
method
边缘近似方法(除了CV_RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)。可取值如下:
CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
CV_CHAIN_APPROX_NONE:将所有的连码点,转换成点。
CV_CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用the flavors of Teh-Chin chain近似算法
的一种。
CV_LINK_RUNS:通过连接水平段的1,使用完全不同的边缘提取算法。使用CV_RETR_LIST检索模式能使用此方法。
offset
偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。
讨论部分cvDrawContours中的案例显示了任何使用轮廓检测连通区域。轮廓可以用于形状分析和目标识别——可以参考文件夹OpenCV sample中的squares.c。
from:http://blog.csdn.net/hz_kevin88/article/details/7775654
最近做连通域分析
最初想自己写,发现好多东西居然不知道怎么做,比如说怎么找内轮廓等
于是改用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,则绘制当前轮廓的外轮廓及他的下一层子轮廓
依次类推
-
int
cvFindContours
(
CvArr*
image,
CvMemStorage*
storage,
CvSeq**
first_contour, int
header_size=sizeof(CvContour), int
mode=CV_RETR_LIST, int
method=CV_CHAIN_APPROX_SIMPLE,
CvPoint
offset=cvPoint(0, 0)
)
¶
-
Finds the contours in a binary image.
Parameters: - image – The source, an 8-bit single channel image. Non-zero pixels are treated as 1’s, zero pixels remain 0’s - the image is treated as binary . To get such a binary image from grayscale, one may use Threshold , AdaptiveThreshold or Canny . The function modifies the source image’s content
- storage – Container of the retrieved contours
- first_contour – Output parameter, will contain the pointer to the first outer contour
- header_size – Size of the sequence header,
if
, and
otherwise
- mode –
Retrieval mode
- CV_RETR_EXTERNAL retrives only the extreme outer contours
- CV_RETR_LIST retrieves all of the contours and puts them in the list
- CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes
- CV_RETR_TREE retrieves all of the contours and reconstructs the full hierarchy of nested contours
- method –
Approximation method (for all the modes, except CV_LINK_RUNS , which uses built-in approximation)
- CV_CHAIN_CODE outputs contours in the Freeman chain code. All other methods output polygons (sequences of vertices)
- CV_CHAIN_APPROX_NONE translates all of the points from the chain code into points
- CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal segments and leaves only their end points
- CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS applies one of the flavors of the Teh-Chin chain approximation algorithm.
- CV_LINK_RUNS uses a completely different contour retrieval algorithm by linking horizontal segments of 1’s. Only the CV_RETR_LISTretrieval mode can be used with this method.
- offset – Offset, by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context
The function retrieves contours from the binary image using the algorithm Suzuki85 . The contours are a useful tool for shape analysis and object detection and recognition.
The function retrieves contours from the binary image and returns the number of retrieved contours. The pointer first_contour is filled by the function. It will contain a pointer to the first outermost contour or NULL if no contours are detected (if the image is completely black). Other contours may be reached from first_contourusing the h_next and v_next links. The sample in the DrawContours discussion shows how to use contours for connected component detection. Contours can be also used for shape analysis and object recognition - see squares.c in the OpenCV sample directory.
Note: the source image is modified by this function.