opencv学习_9 (轮廓提取)

轮廓提取——主要针对二值图像

<1> 轮廓分为外轮廓和内轮廓  如下图:外轮廓以c开头 内轮廓以h开头

opencv学习_9 (轮廓提取)_第1张图片

<2> opencv 提供了寻找轮廓的函数 inttotals = cvFindContours(img, storage,&contours,sizeof(CvContour),  CV_RETR_LIST, CV_CHAIN_APPROX_NONE,cvPoint(0,0));

其中img是二值图像, storage是内存存储序列, contours指向存储的第一个轮廓,

CvMemStorage *storage =cvCreateMemStorage(0);  //内存存储序列

CvSeq *contours = 0;     //指向storage中的序列

 

CV_RETR_LIST表明轮廓在内存中的排列方式,有以下四种:

轮廓的排列方式<在内存中>

     CV_RETR_EXTERNAL:first = c0                         

    CV_RETR_CCOMP:从里到外 从右到左    这是一个双向链表

opencv学习_9 (轮廓提取)_第2张图片

CV_RETR_LIST:

first = c01001 <–> c01000 <–>h0100 <–> h0000 <–> h0100 <–> h0000 <–> c010 <–>c000 <–> h01 <–> h00 <–> c0 这也是双向链表

CV_RETR_TREE

opencv学习_9 (轮廓提取)_第3张图片

<3>案例

结果展示:

opencv学习_9 (轮廓提取)_第4张图片

代码:

#include <iostream>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
using namespace std;
int main()
{
	CvMemStorage *storage = cvCreateMemStorage(0);   // 内存存储序列
	IplImage *img = cvLoadImage("E:\\study_opencv_video\\lesson14_1\\Debug\\55.png", 0);
	IplImage *imgColor = cvCreateImage(cvGetSize(img), 8, 3);
	IplImage *contoursImage = cvCreateImage(cvGetSize(img), 8, 1);

	CvSeq *contours = 0, *contoursTemp = 0;  
	cvZero(contoursImage);
	cvThreshold(img, img, 100, 255, CV_THRESH_BINARY);  // 二值化操作
	cvCvtColor(img, imgColor, CV_GRAY2BGR);
	int totals = cvFindContours(img, storage,&contours, sizeof(CvContour),    //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓
		CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
	contoursTemp = contours;
	int count = 0;
	int i;
	for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next)  /// 这样可以访问每一个轮廓  ====横向轮廓
	{
		for(i = 0; i < contoursTemp -> total; i++)    // 提取一个轮廓的所有坐标点
		{
			CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, i);   // 得到一个轮廓中一个点的函数cvGetSeqElem
			cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);
			cvSet2D(imgColor, pt->y, pt->x, cvScalar(0,0,255,0));
		}
		count ++;
		CvSeq *InterCon = contoursTemp->v_next;     // 访问每个轮廓的纵向轮廓
		for(; InterCon != 0; InterCon = InterCon ->h_next)
		{
			for(i = 0; i < InterCon->total; i++ )
			{
				CvPoint *pt = (CvPoint*)cvGetSeqElem(InterCon, i);
				cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);
				cvSet2D(imgColor, pt->y, pt->x, cvScalar(0, 255, 0, 0));
			}
		}
	}
	cvNamedWindow("contoursImage");
	cvShowImage("contoursImage", contoursImage);
	cvNamedWindow("imgColor");
	cvShowImage("imgColor",imgColor);
	cvWaitKey(0);
	cvReleaseMemStorage(&storage);      // 也要释放内存序列空间
	cvReleaseImage(&contoursImage);
	cvReleaseImage(&imgColor);
	cvDestroyWindow("contoursImage");
	cvDestroyWindow("imgColor");
	return 0;}

作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)

你可能感兴趣的:(轮廓提取,cvFindContours)