对Open CV 中的平面划分相关函数使用探索
2010-09-04 20:48:14 来源:WEB开发网2.应用1-在Delaunay划分结束后获取三角形连接关系
(1) 首先,以边e开始循环查找与其相连的两条边就可以找到一个三角形,对所有边进行相同操作,就可以找到许多三角形,注意,这其中有许多重复的边,需要进行判断。主要代码如下:
for( i = 0; i < total; i++ ) // total是边数目,可以参考Open CV示例程序delaunay.c
{
CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
if( CV_IS_SET_ELEM( edge ))
{
CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge;
CvSubdiv2DEdge t = e;
CvPoint buf[3];
int iPointNum = 3;
for(int j = 0; j < iPointNum; j++ ){
CvSubdiv2DPoint* pt = cvSubdiv2DEdgeOrg( t );
if( !pt ) break;
buf[j] = cvPoint( cvRound(pt->pt.x), cvRound(pt->pt.y));
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
}
if (j == iPointNum) {
AddTriangle(buf); // 添加三角形
}
CV_NEXT_SEQ_ELEM( elem_size, reader );
}
(2) 其次,因为在Delaunay划分中,所有边是有方向的,光通过e进行轮循可能会遗失部分三角形,因此同时还得以e的反向边进行轮循,上面的代码可以改为如下:Bool FindTriangleFromEdge(CvSubdiv2DEdge e)
{
CvSubdiv2DEdge t = e;
CvPoint buf[3];
CvPoint *pBuf = buf;
int iPointNum = 3;
for(int j = 0; j < iPointNum; j++ ){
CvSubdiv2DPoint* pt = cvSubdiv2DEdgeOrg( t );
if( !pt ) break;
buf[j] = cvPoint( cvRound(pt->pt.x), cvRound(pt->pt.y));
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
}
if (j == iPointNum) {
AddTriangle(buf); // 添加三角形
return true;
}
return false;
}
// 调用代码如下
for( i = 0; i < total; i++ )
{
CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
if( CV_IS_SET_ELEM( edge ))
{
CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge;
FindTriangleFromEdge(e);
CvSubdiv2DEdge e1 = (CvSubdiv2DEdge)edge+2; //即next[2]
FindTriangleFromEdge(e1);
}
CV_NEXT_SEQ_ELEM( elem_size, reader );
}
在上面的代码中,是直接采用数组位移法进行各种边的对应的(即edge+2),不过Open CV已经有了自己的实现函数:cvSubdiv2DRotateEdge,上面用红色粗体标注的语句可以换为:CvSubdiv2DEdge e1 = cvSubdiv2DRotateEdge((CvSubdiv2DEdge)edge,2);
对于16个点的输入,Delaunay分割的结果如图2所示。
更多精彩
赞助商链接