K-means的缺点

昨天记录了使用K-means对网格模型进行分割的步骤和一些简单的结果,从昨天的实验结果来看,使用顶点坐标和顶点法向作为K-means聚类的特征得到的分割效果总体上还是不错的。分割结束后,每个顶点会被赋予一个分割的标号。
但是,只使用顶点距离作为聚类得到的结果并没有语义,因此可能会得到一些不太好的聚类结果。

如上图所示,“马”模型的右后腿和两条左腿被分割到了同一个类,这使得分割的结果不具有连通性,因此在后续的学习中,需要对该算法的分割结果进行调整,或者需找更加合适的分割方法。

分割边界的获取

边界获取的思想挺简单,首先遍历网格顶点,筛选出某一特定区域的顶点,对于这一区域中某一顶点,判断其一邻域中的顶点的标号与其自身标号是否相同,如果存在不同标号与自身标号不同的顶点,那么这样的顶点就是边界顶点。找出边界顶点后,为其设置边界标记。同时,记录区域中非边界顶点的个数,以便于计算区域局部的拉普拉斯矩阵。

寻找边界代码如下

void find_Boundary(PolygonMesh::Mesh * _mesh, int area)
{/*_mesh: 输入的网格area: 区域编号*/num_vtx = _mesh->n_vertices();is_boundray.clear();for ( int i = 0; i < num_vtx; i++ ){//默认所有顶点都不是边界当某个顶点的1领域中有一个顶点标号和它不同时,这个顶点为边界顶点is_boundray.push_back(0);}int v_idx = 0;cnt_non_bdy = 0;//非边界顶点个数for (auto v_it = _mesh->vertices_begin();v_it != _mesh->vertices_end();++v_it,v_idx++){if (all_lables[v_idx] == area){for ( auto vv_it = _mesh->vv_begin(v_it); vv_it != _mesh->vv_end(v_it); ++vv_it){OpenMesh::VertexHandle vertex2  = vv_it.handle();int v2_idx = vertex2.idx();//当某个顶点的1领域中有一个顶点标号和它不同时,这个顶点为边界顶点if ( all_lables[v2_idx] !=area ){is_boundray[v_idx]=1;break;}}   }//区域area中的非边界顶点if (all_lables[v_idx] == area && is_boundray[v_idx] !=area ){cnt_non_bdy++;}}
}

需要注意的是,在计算区域的拉普拉斯矩阵时,如果使用L = D - A这种形式的拉普拉斯矩阵,在计算顶点度矩阵和顶点邻接矩阵A时,都要将其邻域中的边界迪昂点排除在外

计算度矩阵和邻接矩阵代码

    int v_idx = 0;int n_vidx = 0;//对同一区域中的顶点重新编号VectorX byd_neibor;//记录每个顶点的边界邻域byd_neibor.setZero(cnt_non_bdy);for(auto v_it = _mesh->vertices_begin();v_it != _mesh->vertices_end();++v_it,++v_idx){if (all_lables[v_idx] == 1 && is_boundray[v_idx] !=1 ){//计算其边界点邻居个数for ( auto vv_it = _mesh->vv_begin(v_it); vv_it != _mesh->vv_end(v_it); ++vv_it){OpenMesh::VertexHandle vertex2  = vv_it.handle();int v2_idx = vertex2.idx();//当某个顶点的1领域中有一个顶点标号和它不同时,这个顶点为边界顶点if ( all_lables[v2_idx] !=1 ){byd_neibor[n_vidx]++;}}   //获得顶点i的度,然后减去边界点个数int val = _mesh->valence(v_it.handle());D_matrix(n_vidx ,n_vidx ) = val - byd_neibor[n_vidx];//获得顶点的1邻域邻接矩阵OpenMesh::VertexHandle vertex1 = v_it.handle();int v1_idx = vertex1.idx();for ( auto vv_it = _mesh->vv_begin(v_it); vv_it != _mesh->vv_end(v_it); ++vv_it){OpenMesh::VertexHandle vertex2  = vv_it.handle();int v2_idx = vertex2.idx();if (is_boundray[v2_idx] != 1)//筛选非边界的邻居顶点{A_matrix(n_vidx,n_vidx) = 1;}}n_vidx ++;//对同一区域中的顶点进行新的编号}}

转载于:https://www.cnblogs.com/scut-linmaojiang/p/4728537.html

网格分割后,边界点的获取方法相关推荐

  1. Spring在3.1版本后的bean获取方法的改变

    xml配置不变,如下 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="ht ...

  2. 获取字符串被分割后的总数组长度 java 类似UBound()方法

    public class test01 {public static void main(String[] args) {ubound("{1},{2},{3}","}, ...

  3. php获取跳转后url,php获取跳转后真实url的方法

    php获取跳转后真实url的方法 发布时间:2020-08-01 14:17:56 来源:亿速云 阅读:68 作者:清晨 这篇文章主要介绍php获取跳转后真实url的方法,文中介绍的非常详细,具有一定 ...

  4. 获取分割后右边的字符串

    在数据库实现字符串分割,然后获取分割后右边的字符串,如: 实现这个功能,主要是从右边开始去获取分割的字符的位置来进行切割: CREATE FUNCTION [dbo].[svf_GetSplitRig ...

  5. IIS 7、8启用nginx代理后日志中获取访客真实IP方法

    所需的步骤取决于您的IIS版本.此操作适用iis7之上版本. 1.下载插件F5XForwardedFor.dll:http://download.west263.net/iis7-rewrite%E6 ...

  6. 【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )

    文章目录 一.不同 Android 系统创建 dex 数组源码对比 二.不同 Android 系统创建 dex 数组源码对比 三. Android 5.1 及以下系统反射方法并创建 Element[] ...

  7. 4种语义分割数据集Cityscapes上SOTA方法总结

    本文分享自华为云社区<语义分割数据集Cityscapes上SOTA方法总结>,原文作者:fdafad. 1 Cityscapes数据集介绍 Cityscapes评测数据集即城市景观数据集, ...

  8. 第三篇 KinectV2骨骼获取原理和获取方法及源代码

    第三篇  KinectV2骨骼获取原理和获取方法及源代码 首先声明一下,本系统所使用的开发环境版本是计算机系统Windows 10.Visual Studio 2013.Opencv3.0和Kinec ...

  9. python下载arcgis地图_互联网地图矢量数据Python获取方法

    原标题:互联网地图矢量数据Python获取方法 慧天地"即可订阅 1.获取高德地图路况信息 1)不使用密钥的方法(5分钟获取一次,只有全国主要城市) 主要利用的网址是 http://repo ...

最新文章

  1. 大型网站架构系列:电商网站架构案例(2)
  2. vue element-ui登录页面源码
  3. 软件集成策略故事连载----对项目的不利影响竟然这么大
  4. 编php矩阵求和,PHP二维数组如何求和?
  5. 鹤岗一中2021年高考成绩查询,2021鹤岗市地区高考成绩排名查询,鹤岗市高考各高中成绩喜报榜单...
  6. Oracle 数据类型 选择自 tjandy 的 Blog
  7. ubuntu 64 位 开发 android 需要安装的 32 位支持库
  8. 找回 Windows 11 丢失的扫雷游戏【新春快乐】
  9. 企业进行OA系统选型的四大标准
  10. python怎么找出列表中的重复数据_找出python列表中重复项的方法
  11. 能否构成三角形的条件代码_中考三角形专题复习:一般三角形知识全面梳理
  12. html怎么绘制中国地图,利用d3.js绘制中国地图
  13. Ubuntu创建用户
  14. FullCalendar日历控件vue使用记录
  15. 华硕bios更改固态硬盘启动_华硕bios怎么设置固态硬盘为第一启动项
  16. html5自动淡入淡出图片,利用html5实现图片的淡入淡出效果
  17. linux内核源码漫游,Linux内核源代码漫游
  18. Unity 检测手机性能,区分高中低端机型
  19. C/C++时间字符串和时间戳的相互转化
  20. 深度学习(Deep Learning)

热门文章

  1. 制作nginx的spec分享
  2. target-action设计模式--主要为Button的方法重写
  3. 关于PHP SESSION
  4. IT销售素质 --善于学习
  5. 网站压力测试工具 webbench
  6. [翻译]RoboChamps城市挑战赛
  7. PAT 乙级 1009. 说反话 (20) Java版
  8. 蓝桥杯 ADV-202算法提高 最长公共子序列(动态规划)
  9. python django 优势_为什么选择Django?
  10. oracle 添加外键,报“未找到父项关键字”