void paint_voronoi( CvSubdiv2D* subdiv, IplImage* img ) { CvSeqReader reader; int i, total = subdiv->edges->total; int elem_size = subdiv->edges->elem_size; cvCalcSubdivVoronoi2D( subdiv ); cvStartReadSeq( (CvSeq*)(subdiv->edges), &reader, 0 ); for( i = 0; i < total; i++ ) { CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr); if( CV_IS_SET_ELEM( edge )) { CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge; // left draw_subdiv_facet( img, cvSubdiv2DRotateEdge( e, 1 )); // right draw_subdiv_facet( img, cvSubdiv2DRotateEdge( e, 3 )); } CV_NEXT_SEQ_ELEM( elem_size, reader ); } }
void run(void) { char win[] = "source"; int i; CvRect rect = { 0, 0, 600, 600 }; CvMemStorage* storage; CvSubdiv2D* subdiv; IplImage* img; CvScalar active_facet_color, delaunay_color, voronoi_color, bkgnd_color; active_facet_color = CV_RGB( 255, 0, 0 ); delaunay_color = CV_RGB( 0,0,0); voronoi_color = CV_RGB(0, 180, 0); bkgnd_color = CV_RGB(255,255,255); img = cvCreateImage( cvSize(rect.width,rect.height), 8, 3 ); cvSet( img, bkgnd_color, 0 ); cvNamedWindow( win, 1 ); storage = cvCreateMemStorage(0); subdiv = init_delaunay( storage, rect ); printf("Delaunay triangulation will be build now interactively.\n" "To stop the process, press any key\n\n"); for( i = 0; i < 200; i++ ) { CvPoint2D32f fp = cvPoint2D32f( (float)(rand()%(rect.width-10)+5), (float)(rand()%(rect.height-10)+5)); locate_point( subdiv, fp, img, active_facet_color ); cvShowImage( win, img ); if( cvWaitKey( 100 ) >= 0 ) break; cvSubdivDelaunay2DInsert( subdiv, fp ); cvCalcSubdivVoronoi2D( subdiv ); cvSet( img, bkgnd_color, 0 ); draw_subdiv( img, subdiv, delaunay_color, voronoi_color ); cvShowImage( win, img ); if( cvWaitKey( 100 ) >= 0 ) break; } cvSet( img, bkgnd_color, 0 ); paint_voronoi( subdiv, img ); cvShowImage( win, img ); cvWaitKey(0); cvReleaseMemStorage( &storage ); cvReleaseImage(&img); cvDestroyWindow( win ); }
CV_IMPL void icvDrawMosaic( CvSubdiv2D * subdiv, IplImage * src, IplImage * dst ) { int i, total = subdiv->edges->total; cvCalcSubdivVoronoi2D( subdiv ); //icvSet( dst, 255 ); for( i = 0; i < total; i++ ) { CvQuadEdge2D *edge = (CvQuadEdge2D *) cvGetSetElem( subdiv->edges, i ); if( edge && CV_IS_SET_ELEM( edge )) { CvSubdiv2DEdge e = (CvSubdiv2DEdge) edge; // left draw_subdiv_facet( subdiv, dst, src, cvSubdiv2DRotateEdge( e, 1 )); // right draw_subdiv_facet( subdiv, dst, src, cvSubdiv2DRotateEdge( e, 3 )); } } }
CV_IMPL CvSubdiv2DPoint* cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt ) { CvSubdiv2DPoint* point = 0; CvPoint2D32f start; CvPoint2D32f diff; CvSubdiv2DPointLocation loc; CvSubdiv2DEdge edge; int i; if( !subdiv ) CV_Error( CV_StsNullPtr, "" ); if( !CV_IS_SUBDIV2D( subdiv )) CV_Error( CV_StsNullPtr, "" ); if( subdiv->edges->active_count <= 3 ) return 0; if( !subdiv->is_geometry_valid ) cvCalcSubdivVoronoi2D( subdiv ); loc = cvSubdiv2DLocate( subdiv, pt, &edge, &point ); switch( loc ) { case CV_PTLOC_ON_EDGE: case CV_PTLOC_INSIDE: break; default: return point; } point = 0; start = cvSubdiv2DEdgeOrg( edge )->pt; diff.x = pt.x - start.x; diff.y = pt.y - start.y; edge = cvSubdiv2DRotateEdge( edge, 1 ); for( i = 0; i < subdiv->total; i++ ) { CvPoint2D32f t; for(;;) { assert( cvSubdiv2DEdgeDst( edge )); t = cvSubdiv2DEdgeDst( edge )->pt; if( icvIsRightOf2( t, start, diff ) >= 0 ) break; edge = cvSubdiv2DGetEdge( edge, CV_NEXT_AROUND_LEFT ); } for(;;) { assert( cvSubdiv2DEdgeOrg( edge )); t = cvSubdiv2DEdgeOrg( edge )->pt; if( icvIsRightOf2( t, start, diff ) < 0 ) break; edge = cvSubdiv2DGetEdge( edge, CV_PREV_AROUND_LEFT ); } { CvPoint2D32f tempDiff = cvSubdiv2DEdgeDst( edge )->pt; t = cvSubdiv2DEdgeOrg( edge )->pt; tempDiff.x -= t.x; tempDiff.y -= t.y; if( icvIsRightOf2( pt, t, tempDiff ) >= 0 ) { point = cvSubdiv2DEdgeOrg( cvSubdiv2DRotateEdge( edge, 3 )); break; } } edge = cvSubdiv2DSymEdge( edge ); } return point; }