该程序演示了 delaunay 三角剖分和 voronoi 细分的迭代构造。

This program demonstrates iterativeconstruction of delaunaytriangulation and voronoitessellation.

它在图像中绘制一组随机点,然后对它们进行三角测量。

It draws a random set of points in an imageand then delaunay triangulates them.

该程序以交互方式构建三角形,您可以通过按任意键来停止此过程

This program builds the triangulationinteractively, you may stop this process by hitting any key

视频演示

源码:

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>using namespace cv;
using namespace std;static void help(char** argv)
{cout << "\nThis program demonstrates iterative construction of\n""delaunay triangulation and voronoi tessellation.\n""It draws a random set of points in an image and then delaunay triangulates them.\n""Usage: \n";cout << argv[0];cout << "\n\nThis program builds the triangulation interactively, you may stop this process by\n""hitting any key.\n";
}static void draw_subdiv_point( Mat& img, Point2f fp, Scalar color )
{circle( img, fp, 3, color, FILLED, LINE_8, 0 );//绘制圆点
}static void draw_subdiv( Mat& img, Subdiv2D& subdiv, Scalar delaunay_color )
{
#if 1vector<Vec6f> triangleList;subdiv.getTriangleList(triangleList);vector<Point> pt(3);for( size_t i = 0; i < triangleList.size(); i++ )//绘制所有三角形{Vec6f t = triangleList[i];pt[0] = Point(cvRound(t[0]), cvRound(t[1]));pt[1] = Point(cvRound(t[2]), cvRound(t[3]));pt[2] = Point(cvRound(t[4]), cvRound(t[5]));line(img, pt[0], pt[1], delaunay_color, 1, LINE_AA, 0);line(img, pt[1], pt[2], delaunay_color, 1, LINE_AA, 0);line(img, pt[2], pt[0], delaunay_color, 1, LINE_AA, 0);}
#elsevector<Vec4f> edgeList;subdiv.getEdgeList(edgeList);for( size_t i = 0; i < edgeList.size(); i++ )//绘制所有边{Vec4f e = edgeList[i];Point pt0 = Point(cvRound(e[0]), cvRound(e[1]));Point pt1 = Point(cvRound(e[2]), cvRound(e[3]));line(img, pt0, pt1, delaunay_color, 1, LINE_AA, 0);}
#endif
}static void locate_point( Mat& img, Subdiv2D& subdiv, Point2f fp, Scalar active_color )
{int e0=0, vertex=0;//返回指定点所属三角形相关信息/**param[in] pt 指定点*param[out] edge 指定点所属三角形最初的边ID*param[out] vertex 指定点所属三角形最初的頂点ID*/subdiv.locate(fp, e0, vertex);if( e0 > 0 ){int e = e0;do{Point2f org, dst;if( subdiv.edgeOrg(e, &org) > 0 && subdiv.edgeDst(e, &dst) > 0 )//找到指定边的 起点和终点line(img, org, dst, active_color, 3, LINE_AA, 0);//绘制直线e = subdiv.getEdge(e, Subdiv2D::NEXT_AROUND_LEFT);//获取下一个左边的边}while( e != e0 );// }draw_subdiv_point( img, fp, active_color );//在fp位置绘制圆点
}//绘制voronoi图
static void paint_voronoi( Mat& img, Subdiv2D& subdiv )
{vector<vector<Point2f> > facets;vector<Point2f> centers;subdiv.getVoronoiFacetList(vector<int>(), facets, centers);vector<Point> ifacet;vector<vector<Point> > ifacets(1);for( size_t i = 0; i < facets.size(); i++ ){ifacet.resize(facets[i].size());for( size_t j = 0; j < facets[i].size(); j++ )ifacet[j] = facets[i][j];Scalar color;color[0] = rand() & 255;color[1] = rand() & 255;color[2] = rand() & 255;fillConvexPoly(img, ifacet, color, 8, 0);ifacets[0] = ifacet;polylines(img, ifacets, true, Scalar(), 1, LINE_AA, 0);circle(img, centers[i], 3, Scalar(), FILLED, LINE_AA, 0);}
}int main( int argc, char** argv )
{cv::CommandLineParser parser(argc, argv, "{help h||}");if (parser.has("help")){help(argv);return 0;}Scalar active_facet_color(0, 0, 255), delaunay_color(255,255,255);Rect rect(0, 0, 600, 600);Subdiv2D subdiv(rect);//三角网剖分Mat img(rect.size(), CV_8UC3);img = Scalar::all(0);string win = "Delaunay Demo";cv::imshow(win, img);//黑色背景图for( int i = 0; i < 200; i++ ){   //随机200个点Point2f fp( (float)(rand()%(rect.width-10)+5),(float)(rand()%(rect.height-10)+5));locate_point( img, subdiv, fp, active_facet_color );//红色圆点,绘制连接该点的三角形cv::imshow( win, img );if(cv::waitKey( 100 ) >= 0 )break;subdiv.insert(fp);//插入新点img = Scalar::all(0);//清空图像draw_subdiv( img, subdiv, delaunay_color );//绘制Delaunay三角剖分图cv::imshow( win, img );if(cv::waitKey( 100 ) >= 0 )break;}img = Scalar::all(0);//再次清空图像paint_voronoi( img, subdiv );//绘制Voronoi图cv::imshow( win, img );cv::waitKey(0);return 0;
}

参考:

三角剖分和Delaunay剖分的定义

如何把一个散点集合剖分成不均匀的三角形网格,这就是散点集的三角剖分问题,散点集的三角剖分,对数值分析以及图形学来说,都是极为重要的一项预处理技术

Delaunay三角剖分的特性

以下是Delaunay剖分所具备的优异特性:

1. 最接近:以最近邻的三点形成三角形,且各线段(三角形的边)皆不相交。

2. 唯一性:不论从区域何处开始构建,最终都将得到一致的结果。

3. 最优性:任意两个相邻三角形形成的凸四边形的对角线如果可以互换的话,那么两个三角形六个内角中最小的角度不会变大。

4. 最规则:如果将三角网中的每个三角形的最小角进行升序排列,则Delaunay三角网的排列得到的数值最大。

5. 区域性:新增、删除、移动某一个顶点时只会影响临近的三角形。

6. 具有凸多边形的外壳:三角网最外层的边界形成一个凸多边形的外壳。

Delaunay剖分是一种三角剖分的标准,实现它有多种算法。

Lawson算法 Bowyer-Watson算法

Delaunay三角剖分实践与原理 - 知乎(zhihu.com)

https://zhuanlan.zhihu.com/p/42331420

[图形算法]Delaunay三角剖分算法 - 塞风朔雪 - 博客园 (cnblogs.com)

https://www.cnblogs.com/RenLiQQ/archive/2008/02/06/1065399.html

二维三角剖分通常用于计算机视觉中标记空间目标的特征或运动场景跟踪,目标识别,或两个不同的摄像机的场景匹配

Voronoi划分_lzhf1122的博客-CSDN博客_voronoi剖分

https://blog.csdn.net/lzhf1122/article/details/72866521

Voronoi图的简单方法_爱分享的小佳的博客-CSDN博客_voronoi图法

https://blog.csdn.net/gumenghua_com1/article/details/109839253

OpenCV三角网剖分 SubDiv2D 详解_唐国平的博客-CSDN博客

https://blog.csdn.net/m0_37742084/article/details/65437689

class SubDiv2D{// 两种构造函数Subdiv2D();// 第一种无参的构造函数/**param[in] rect 空的Delaunay細分割的参数。例如,针对整个图片的场合,cv::Rect(0,0,width,height)*/Subdiv2D(Rect rect);//初始化void initDelaunay(Rect rect);//往Delaunay三角形里面追加点int insert(Point2f pt);void insert(const vector<Point2f>& ptvec);//返回指定点所属三角形相关信息/**param[in] pt 指定点*param[out] edge 指定点所属三角形最初的边ID*param[out] vertex 指定点所属三角形最初的頂点ID*/int locate(Point2f pt, int& edge, int& vertex);// 找到与指定点最近的细分割的顶点。/**param[in] pt 指定点*param[out] nearestPt 最近的细分割的顶点*/int findNearest(Point2f pt, Point2f* nearestPt=0);//找到Delaunay边的集合/*\param[out] edgeList 边情报的集合。(始点的x座標和y座標、終点的x座標和y座標)*/void getEdgeList(vector<Vec4f>& edgeList) const;// 找到Delaunay三角形的顶点/*\param[out] traiangleList 三角形顶点的集合。(3个点的x座標和y座標)*/void getTriangleList(vector<Vec6f>& triangleList) const;// 找到Voronoi区域/*\param[in] idx Voronoi区域的ID\param[out] facetList 包围Voronoi区域的顶点\param[out] facetCenters Voronoi区域的母点*/void getVoronoiFacetList(const vector<int>& idx, vector<vector<Point2f> >& facetList,vector<Point2f>& facetCenters);//!取得顶点/*!\param[in] vertex 顶点ID\param[out] firstEdge 与顶点最接近的边的ID\return 顶点的座標*/Point2f getVertex(int vertex, int* firstEdge=0) const;//! 找到指定边关联的一条边/*!\param[in] edge 边的ID\param[in] nextEdgeType 指定要取到的边和指定边有怎样关系。\return 关联边的ID*/int getEdge( int edge, int nextEdgeType ) const;int nextEdge(int edge) const;int rotateEdge(int edge, int rotate) const;int symEdge(int edge) const;//找到指定边的开始点/*\param[in] edge 指定边的ID\param[in] orgpt 开始点坐标。\return 取到的场合,返回>0的整数*/int edgeOrg(int edge, Point2f* orgpt=0) const;//找到指定边的终点/*!\param[in] edge 指定边的ID\param[in] dstpt 终点坐标。\return 取到的场合,返回>0的整数*/int edgeDst(int edge, Point2f* dstpt=0) const;
}

【opencv450-samples】delaunay 三角剖分和 voronoi 细分相关推荐

  1. 如何使用OpenCV进行Delaunay三角剖分和Voronoi图

    图1.左:使用dlib检测到具有标志性建筑的奥巴马总统图像.中心:地标的Delaunay三角剖分.右:对应的Voronoi图. 俄国数学家鲍里斯·尼古拉耶维奇·德劳内(Boris Nikolaevic ...

  2. OpenCV delaunay三角剖分和voronoi镶嵌的实例(附完整代码)

    OpenCV delaunay三角剖分和voronoi镶嵌的实例 OpenCV delaunay三角剖分和voronoi镶嵌的实例 OpenCV delaunay三角剖分和voronoi镶嵌的实例 # ...

  3. 数字图像处理 Delaunay三角剖分和Voronoi图

    一.什么是Delaunay三角剖分? 给定平面中的一组点,三角测量是指将平面细分为三角形,以这些点为顶点.在下图1中,我们在左图像中看到一组地标,在中间图像中看到三角剖分.一组点可以有许多可能的三角剖 ...

  4. 基于C++(MFC)的二维Delaunay三角剖分与Voronoi图的算法及代码

    一. Delaunay三角网 Delaunay三角网的特性: (1)空圆性,任一三角形外接圆内部不包含其他点. (2)最接近:以最近临的三点形成三角形,且各线段(三角形的边)皆不相交. (3)唯一性: ...

  5. Delaunay三角剖分----OpenCV

    转自:https://blog.csdn.net/newthinker_wei/article/details/45598769 相关文章:OpenCV三角剖分的遍历和纹理映射:http://blog ...

  6. openCV【实践系列】5——使用OpenCV进行Delaunay三角剖分

    使用OpenCV进行Delaunay三角剖分和Voronoi图 图1:左图奥巴马总统使用dlib检测到标志点,中间Delaunay三角剖分的标志点,右图:相应的Voronoi图     在面部标志的众 ...

  7. OpenCV——Delaunay三角剖分(C++实现)

    最近做三角剖分发现了一篇很好的博客,其中的代码都可以实现,特在此分享给大家,希望可以一起学习,有问题共同探讨. ---------转载源--------- ---------------------- ...

  8. OpenCV——Delaunay三角剖分

    转载请注明:http://blog.csdn.net/raby_gyl/article/details/17409717 相关文章:OpenCV三角剖分的遍历和纹理映射:http://blog.csd ...

  9. OpenCV——Delaunay三角剖分 [转载]

    本博客转载自 http://blog.csdn.net/raby_gyl/article/details/17409717 请其他同学转载时注明原始文章的出处! Delaunay三角剖分是1934年发 ...

最新文章

  1. 前来推荐一本比较喜欢的读物——《浪潮之巅》
  2. django中自定义标签和过滤器
  3. macOS 开启 VNC 远程桌面和 SSH 服务
  4. python applymap_Python pandas.DataFrame.applymap函数方法的使用
  5. postgresql主从备份_PostgreSQL主从流复制与手动主备切换架构
  6. 2013年c语言课后作业答案,2013年计算机二级C语言课后模拟题三及答案
  7. retrofit2.6.0_RxAndroid和Retrofit 2.0
  8. mysql插10万条数据_如何快速安全的插入千万条数据?
  9. Codeforces 964B(贪心)
  10. Java中parseInt()和valueOf(),toString()的区别
  11. conda查看已装包_conda一个包管理器
  12. DataPipeline王睿:业务异常实时自动化检测 — 基于人工智能的系统实战
  13. Java中的Stream流
  14. python爬取链家网_Python爬链家网租房信息
  15. 报错Replace Autoprefixer browsers option to Browserslist config.
  16. 闪送,为何能比顺丰送得更快?
  17. [Eigen中文文档] 归约、访问者和广播
  18. 云服务器大数据高可用集群搭建-----hadoop篇
  19. STM32F4之按键(二)
  20. ContentProvider android:exported = “true”

热门文章

  1. make[2]:***没有规则制作目标XXX,由XXX需求。停止。
  2. 盖塔机器人好_[转载]盖塔机器人的十大谜团
  3. OpenCV,OpenGL,DirectX三者的区别
  4. 比较DirectX和OpenGL的区别
  5. matlab中(:)的部分使用
  6. soul显示服务器错误,Soul接入一个Http服务
  7. 科研经验002:如何礼貌地要代码的邮件模板
  8. 一个骨灰级玩家的游戏加速器使用心得分享
  9. 第一天:Hbase 概述
  10. VS2017添加qt-vsaddin-msvc2017-2.7.1.vsix