CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
//传入图像必须是8位单通道,将被修改
int iCount=cvFindContours( imgDst, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_CODE );
//检索模式,可取值如下:
//CV_RETR_EXTERNAL:只检索最外面的轮廓;
//CV_RETR_LIST:检索所有的轮廓,并将其放入list中;
//CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
//CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。
//边缘近似方法(除了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检索模式能使用此方法。
rectVec->clear();
for( ; contour != 0; contour = contour->h_next )
{
//if(fabs(area) < 100)
//{
// continue;
//}
//得到外部轮廓
if (iMode==1 || iMode==3)
{
CvRect rect=((CvContour*)contour)->rect;
CRect rectTemp(rect.x,rect.y,rect.x+rect.width,rect.y+rect.height);
if (bHasROI)
{
rectTemp.OffsetRect(iROIx1,iROIy1);
}
rectVec->push_back(rectTemp);
if (contoursPtVec!=NULL)
{
//ContoursPoint cPt;
vector<CPoint> *ptVec=new vector<CPoint>;
CString str,strstr;
strstr.Empty();
for (int i=0; i<contour->total; i++)
{
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,contour,i);
ptVec->push_back(CPoint(p->x,p->y));
str.Format(_T("%d\t%d %d\n"),i+1,p->x,p->y);
strstr+=str;
}
AfxMessageBox(strstr);
contoursPtVec->push_back(ptVec);
}
if (1==1)//返回freemain链码 设置cvFindContours参数=CV_CHAIN_CODE
{
CvSeqReader reader;
int i, total = contour->total;
cvStartReadSeq( (CvSeq*)contour, &reader, 0 );
CvChainPtReader reader1;
cvStartReadChainPoints((CvChain*)contour, &reader1);
CString str,strstr;
for( i = 0; i < total; i++ )
{
char code;
CV_READ_SEQ_ELEM( code, reader );
CvPoint pt;
CV_READ_CHAIN_POINT(pt,reader1);
//printf(" %d : \n",code);//得到轮廓的Freeman链码序列
str.Format(_T("%d %d\t%d\t%d %d\n"),total,i+1,code,reader1.pt.x,reader1.pt.y);
//AfxMessageBox(_T("check"));
strstr+=str;
}
AfxMessageBox(strstr);
}
// //得到轮廓面积,长度
// double area = cvContourArea( contour,CV_WHOLE_SEQ );
// double length=cvArcLength(contour,CV_WHOLE_SEQ );
// CString str;
// str.Format(_T("外%.2f %.2f (%d %d %d %d)"),fabs(area),length,rectTemp.left,rectTemp.top,rectTemp.right,rectTemp.bottom);
// AfxMessageBox(str);
}
if (iMode==2 || iMode==3)
{
//CV_RETR_CCOMP 时得到孔洞
CvSeq* contourVNext = contour->v_next;
for (; contourVNext!=0; contourVNext=contourVNext->h_next)
{
CvRect rect=((CvContour*)contourVNext)->rect;
CRect rectTemp(rect.x,rect.y,rect.x+rect.width,rect.y+rect.height);
rectTemp.InflateRect(-1,-1);
if (bHasROI)
{
rectTemp.OffsetRect(iROIx1,iROIy1);
}
rectVec->push_back(rectTemp);
// //得到轮廓面积,长度
// double area = cvContourArea( contourVNext,CV_WHOLE_SEQ );
// double length=cvArcLength(contourVNext,CV_WHOLE_SEQ );
// CString str;
// str.Format(_T("内%.2f %.2f (%d %d %d %d)"),fabs(area),length,rectTemp.left,rectTemp.top,rectTemp.right,rectTemp.bottom);
// AfxMessageBox(str);
}
}
}
CvSeq* contour = 0;
//传入图像必须是8位单通道,将被修改
int iCount=cvFindContours( imgDst, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_CODE );
//检索模式,可取值如下:
//CV_RETR_EXTERNAL:只检索最外面的轮廓;
//CV_RETR_LIST:检索所有的轮廓,并将其放入list中;
//CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
//CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。
//边缘近似方法(除了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检索模式能使用此方法。
rectVec->clear();
for( ; contour != 0; contour = contour->h_next )
{
//if(fabs(area) < 100)
//{
// continue;
//}
//得到外部轮廓
if (iMode==1 || iMode==3)
{
CvRect rect=((CvContour*)contour)->rect;
CRect rectTemp(rect.x,rect.y,rect.x+rect.width,rect.y+rect.height);
if (bHasROI)
{
rectTemp.OffsetRect(iROIx1,iROIy1);
}
rectVec->push_back(rectTemp);
if (contoursPtVec!=NULL)
{
//ContoursPoint cPt;
vector<CPoint> *ptVec=new vector<CPoint>;
CString str,strstr;
strstr.Empty();
for (int i=0; i<contour->total; i++)
{
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,contour,i);
ptVec->push_back(CPoint(p->x,p->y));
str.Format(_T("%d\t%d %d\n"),i+1,p->x,p->y);
strstr+=str;
}
AfxMessageBox(strstr);
contoursPtVec->push_back(ptVec);
}
if (1==1)//返回freemain链码 设置cvFindContours参数=CV_CHAIN_CODE
{
CvSeqReader reader;
int i, total = contour->total;
cvStartReadSeq( (CvSeq*)contour, &reader, 0 );
CvChainPtReader reader1;
cvStartReadChainPoints((CvChain*)contour, &reader1);
CString str,strstr;
for( i = 0; i < total; i++ )
{
char code;
CV_READ_SEQ_ELEM( code, reader );
CvPoint pt;
CV_READ_CHAIN_POINT(pt,reader1);
//printf(" %d : \n",code);//得到轮廓的Freeman链码序列
str.Format(_T("%d %d\t%d\t%d %d\n"),total,i+1,code,reader1.pt.x,reader1.pt.y);
//AfxMessageBox(_T("check"));
strstr+=str;
}
AfxMessageBox(strstr);
}
// //得到轮廓面积,长度
// double area = cvContourArea( contour,CV_WHOLE_SEQ );
// double length=cvArcLength(contour,CV_WHOLE_SEQ );
// CString str;
// str.Format(_T("外%.2f %.2f (%d %d %d %d)"),fabs(area),length,rectTemp.left,rectTemp.top,rectTemp.right,rectTemp.bottom);
// AfxMessageBox(str);
}
if (iMode==2 || iMode==3)
{
//CV_RETR_CCOMP 时得到孔洞
CvSeq* contourVNext = contour->v_next;
for (; contourVNext!=0; contourVNext=contourVNext->h_next)
{
CvRect rect=((CvContour*)contourVNext)->rect;
CRect rectTemp(rect.x,rect.y,rect.x+rect.width,rect.y+rect.height);
rectTemp.InflateRect(-1,-1);
if (bHasROI)
{
rectTemp.OffsetRect(iROIx1,iROIy1);
}
rectVec->push_back(rectTemp);
// //得到轮廓面积,长度
// double area = cvContourArea( contourVNext,CV_WHOLE_SEQ );
// double length=cvArcLength(contourVNext,CV_WHOLE_SEQ );
// CString str;
// str.Format(_T("内%.2f %.2f (%d %d %d %d)"),fabs(area),length,rectTemp.left,rectTemp.top,rectTemp.right,rectTemp.bottom);
// AfxMessageBox(str);
}
}
}