Delaunay三角形和Voronoi划分的迭代式构造

Delaunay三角形和Voronoi划分的迭代式构造

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <opencv2/legacy/legacy.hpp>//opencv2添加此头文件
CvSubdiv2D* init_delaunay(CvMemStorage* storage,
    CvRect rect)
{
    CvSubdiv2D* subdiv;
    subdiv = cvCreateSubdiv2D(CV_SEQ_KIND_SUBDIV2D, 
        sizeof(*subdiv),
        sizeof(CvSubdiv2DPoint),
        sizeof(CvQuadEdge2D),
        storage);
    cvInitSubdivDelaunay2D(subdiv, rect);
    return subdiv;
}

void draw_subdiv_point(IplImage* img, CvPoint2D32f fp, CvScalar color)
{
    cvCircle(img, cvPoint(cvRound(fp.x), cvRound(fp.y)), 3, color, CV_FILLED, 8, 0);
}

void draw_subdiv_edge(IplImage* img, CvSubdiv2DEdge edge, CvScalar color)
{
    CvSubdiv2DPoint* org_pt;
    CvSubdiv2DPoint* dst_pt;
    CvPoint2D32f org;
    CvPoint2D32f dst;
    CvPoint iorg, idst;
    org_pt = cvSubdiv2DEdgeOrg(edge);
    dst_pt = cvSubdiv2DEdgeDst(edge);
    if (org_pt && dst_pt)
    {
        org = org_pt->pt;
        dst = dst_pt->pt;
        iorg = cvPoint(cvRound(org.x), cvRound(org.y));
        idst = cvPoint(cvRound(dst.x), cvRound(dst.y));
        cvLine(img, iorg, idst, color, 1, CV_AA, 0);
    }
}

void draw_subdiv(IplImage* img, CvSubdiv2D* subdiv,
    CvScalar delaunay_color, CvScalar voronoi_color)
{
    CvSeqReader reader;
    int i, total = subdiv->edges->total;
    int elem_size = subdiv->edges->elem_size;
    cvStartReadSeq((CvSeq*)(subdiv->edges), &reader, 0);
    for (i = 0; i < total; i++)
    {
        CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
        if (CV_IS_SET_ELEM(edge))
        {
            draw_subdiv_edge(img, (CvSubdiv2DEdge)edge + 1, voronoi_color);
            draw_subdiv_edge(img, (CvSubdiv2DEdge)edge, delaunay_color);
        }
        CV_NEXT_SEQ_ELEM(elem_size, reader);
    }
}

void locate_point(CvSubdiv2D* subdiv, CvPoint2D32f fp, IplImage* img,
    CvScalar active_color)
{
    CvSubdiv2DEdge e;
    CvSubdiv2DEdge e0 = 0;
    CvSubdiv2DPoint* p = 0;
    cvSubdiv2DLocate(subdiv, fp, &e0, &p);
    if (e0)
    {
        e = e0;
        do
        {
            draw_subdiv_edge(img, e, active_color);
            e = cvSubdiv2DGetEdge(e, CV_NEXT_AROUND_LEFT);
        } while (e != e0);
    }
    draw_subdiv_point(img, fp, active_color);
}

void draw_subdiv_facet(IplImage* img, CvSubdiv2DEdge edge)
{
    CvSubdiv2DEdge t = edge;
    int i, count = 0;
    CvPoint* buf = 0;
    // count number of edges in facet
    do
    {
        count++;
        t = cvSubdiv2DGetEdge(t, CV_NEXT_AROUND_LEFT);
    } while (t != edge);
    buf = (CvPoint*)malloc(count * sizeof(buf[0]));
    // gather points
    t = edge;
    for (i = 0; i < count; i++)
    {
        CvSubdiv2DPoint* pt = cvSubdiv2DEdgeOrg(t);
        if (!pt) break;
        buf[i] = cvPoint(cvRound(pt->pt.x), cvRound(pt->pt.y));
        t = cvSubdiv2DGetEdge(t, CV_NEXT_AROUND_LEFT);
    }
    if (i == count)
    {
        CvSubdiv2DPoint* pt = cvSubdiv2DEdgeDst(cvSubdiv2DRotateEdge(edge, 1));
        cvFillConvexPoly(img, buf, count, CV_RGB(rand() & 255, rand() & 255, rand() & 255), CV_AA, 0);
        cvPolyLine(img, &buf, &count, 1, 1, CV_RGB(0, 0, 0), 1, CV_AA, 0);
        draw_subdiv_point(img, pt->pt, CV_RGB(0, 0, 0));
    }
    free(buf);
}
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);
}
int main(int argc, char** argv)
{
    run();
    return 0;
}

这里写图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值