【CGAL】提取中心线

vtk提取中心线的思路是依次寻找最大内接球,cgal是把模型封闭,让后无线细化成一条线,我测试感觉点会突然离散,不知什么原因

vtkSmartPointer<vtkPolyData> RefinementComputingCenterLines(const vtkSmartPointer<vtkPolyData> surface) {vtkSmartPointer<vtkPolyData> centerline_input_surface;// vtk 表面整理vtkNew<vtkCleanPolyData> surface_cleaner;surface_cleaner->SetInputData(surface);surface_cleaner->Update();// vtk 三角形相交检查vtkNew<vtkTriangleFilter> surface_triangulator;surface_triangulator->SetInputConnection(surface_cleaner->GetOutputPort());surface_triangulator->PassLinesOff();surface_triangulator->PassVertsOff();surface_triangulator->Update();// vtk 表面封闭vtkNew<vtkvmtkCapPolyData> surface_capper;surface_capper->SetInputConnection(surface_triangulator->GetOutputPort());surface_capper->SetDisplacement(0);surface_capper->SetInPlaneDisplacement(0);surface_capper->Update();surface_cleaner->SetInputData(surface_capper->GetOutput());surface_cleaner->Update();surface_triangulator->SetInputConnection(surface_cleaner->GetOutputPort());surface_triangulator->PassLinesOff();surface_triangulator->PassVertsOff();surface_triangulator->Update();centerline_input_surface = surface_triangulator->GetOutput();// 转换为off模型STL2OFF("tmp.off", centerline_input_surface);// 提取骨骼std::ifstream input("tmp.off");Polyhedron tmesh;input >> tmesh;if (!CGAL::is_triangle_mesh(tmesh)) {std::cout << "Input geometry is not triangulated." << std::endl;return centerline_input_surface;}Skeleton skeleton;CGAL::extract_mean_curvature_flow_skeleton(tmesh, skeleton);vtkNew<vtkPoints> points_tmp;vtkNew<vtkCellArray> vertices_tmp;for (quint32 i = 0; i < boost::num_edges(skeleton); ++i) {points_tmp->InsertNextPoint(skeleton[i].point[0],skeleton[i].point[1],skeleton[i].point[2]);vertices_tmp->InsertNextCell(1);vertices_tmp->InsertCellPoint(i);}vtkNew<vtkPolyData> centerline_output_surface;centerline_output_surface->SetPoints(points_tmp);centerline_output_surface->SetVerts(vertices_tmp);return centerline_output_surface;
}
void STL2OFF(const QString off_filename,vtkSmartPointer<vtkPolyData> surface_) {if (surface_ == nullptr) {return;}if (off_filename.isEmpty()) {return;}double x[3];QFile file(off_filename);file.open(QIODevice::WriteOnly);file.close();if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {QTextStream stream(&file);stream.seek(file.size());stream << "OFF" << "\n";stream << surface_->GetNumberOfPoints() << " "<< surface_->GetNumberOfCells() << " 0\n";for (qint32 ww = 0; ww < surface_->GetNumberOfPoints() ; ww++) {surface_->GetPoint(ww, x);stream << x[0] << " " << x[1] << " " << x[2] << "\n";}for (qint32 ww = 0; ww < surface_->GetNumberOfCells() ; ww++) {stream << surface_->GetCell(ww)->GetNumberOfPoints() << " ";for (qint32 i = 0; i <surface_->GetCell(ww)->GetNumberOfPoints(); i++) {stream << surface_->GetCell(ww)->GetPointId(i) << " ";}stream << "\n";}file.close();}
}bool OFF2STL(const QString off_filename, vtkSmartPointer<vtkPolyData> surface_) {std::string inputFilename = off_filename.toLocal8Bit().data();std::ifstream fin(inputFilename.c_str());vtkSmartPointer<vtkPolyData> surface = CustomReader(fin);vtkSmartPointer<vtkTriangleFilter> triangleFilter =vtkSmartPointer<vtkTriangleFilter>::New();triangleFilter->SetInputData(surface);vtkSmartPointer<vtkPolyDataNormals> normals =vtkSmartPointer<vtkPolyDataNormals>::New();normals->SetInputConnection(triangleFilter->GetOutputPort());normals->ConsistencyOn();normals->SplittingOff();vtkSmartPointer<vtkMassProperties> massProperties =vtkSmartPointer<vtkMassProperties>::New();massProperties->SetInputConnection(normals->GetOutputPort());massProperties->Update();if (massProperties->GetSurfaceArea() > 0.01) {surface_ = surface;fin.close();if (surface_ == nullptr) {return false;}return true;}return false;
}vtkSmartPointer<vtkPolyData> CustomReader(istream &infile) {char buf[1000];infile.getline(buf, 1000);if (strcmp(buf, "off") == 0 || strcmp(buf, "OFF") == 0) {vtkIdType number_of_points, number_of_triangles, number_of_lines;infile >> number_of_points >> number_of_triangles >> number_of_lines;vtkSmartPointer<vtkPoints> points= vtkSmartPointer<vtkPoints>::New();points->SetNumberOfPoints(number_of_points);for (vtkIdType i = 0; i < number_of_points; i++) {double x, y, z;infile >> x >> y >> z;points->SetPoint(i, x, y, z);}vtkSmartPointer<vtkCellArray> polys= vtkSmartPointer<vtkCellArray>::New();qint32 n;vtkIdType type;for (vtkIdType i = 0; i < number_of_triangles; i++) {infile >> n;polys->InsertNextCell(n);for (; n > 0; n--) {infile >> type;polys->InsertCellPoint(type);}}vtkPolyData *polydata = vtkPolyData::New();polydata->SetPoints(points);polydata->SetPolys(polys);return polydata;}vtkPolyData *polydata = vtkPolyData::New();return polydata;
}

【CGAL】提取中心线相关推荐

  1. 利用matlab提取中心线

    先看看代码运行结果(红色部分表示河流中心线,黑色表示河流两岸!): 注: 1. 由于河流两岸的坐标不是等距采样,所以无法保证100%准确,只要按着要求处理河岸坐标数据Shape文件,能保证95%以上能 ...

  2. 灰度重心法提取中心线遇到的问题

    import cv2 img = cv2.imread("E:/tuku/2019-10-28_10_36_21_370.bmp",0) median = cv2.Gaussian ...

  3. 基于OpenCV实战:提取中心线

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|AI算法与图像处理 问题 前几天有个人问了我一个问题,问 ...

  4. cvtcolor python opencv_二值分析 | OpenCV + skimage如何提取中心线

    点击上方蓝字关注我们 微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识 问题 前几天有个人问了我一个问题,问题是这样的,他有如下的一张二值图像: 怎么得到白色Blob中心线,他希望的 ...

  5. 转:ArcGIS提取面状道路中心线(转载)

    1.首先把所有的面要素merge成一个要素 2.把merge后的数据转成线数据 3.此时转换后的线数据一定是闭合的,为了防止提取中心线失败(只提取出外围轮廓)我们在随意一个道路末端使用打断工具打一个开 ...

  6. 基于灰度质心法和骨架的激光中心线提取

    之前博主一直在做线结构光成像,硬件比较垃圾,相机加镜头和线激光器总共成本在1000以内,精度在0.1mm左右,感觉这种成本做出来还是不错的,其实主要大部分时间花在了分析上来达到最好的效果. 一般对于激 ...

  7. (代码已更新)QT 环境下 用opencv 进行骨架细化(骨架提取)得到图像中心线

    之前的任务是把如下的一个直钢管图像进行处理,提取出中心线,用到了骨架细化算法以及一些常用的opencv处理.思路就是: 预处理通过灰度得到二值图像--二值图形态学处理--骨架细化提取中心线--霍夫概率 ...

  8. 基于Arcgis 利用道路面要素提取道路中心线的方法

    转载自李远祥博客:http://blog.csdn.net/liyuanxiang1984 http://blog.csdn.net/liyuanxiang1984/article/details/5 ...

  9. ArcGIS提取面状道路中心线

    老生常谈的问题,其实在BBS里已经讨论过好多次了,在这里再整理一次分享给大家 在数据有备份的情况: 1.首先把所有的面要素merge成一个要素 2.把merge后的数据转成线数据 3.此时转换后的线数 ...

  10. ArcGIS基础:提取道路中心线

    本实验为对道路路面数据进行中心线提取 以路边两侧边界为准,运用等分的办法实现道路中心线提取,原始数据如下所示(来源于网络). 道路顶端有一些圆弧段的部分,需要把其去除. 首先要做的是面转线操作,如下, ...

最新文章

  1. 录制短视频的录制按钮边框计时效果
  2. OVS ofproto(二十三)
  3. SpringApplication.run做了哪些事情
  4. MiniDao Framework 1.3.0 发布,J2EE持久化解决方案
  5. gson Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path
  6. shell中可能经常能看到:/dev/null 21
  7. CSS:模拟实现QQ浏览器
  8. B+树 mysql
  9. 下列选项中 采用边界值平滑_2014年10月湖南自考:软件工程全真模拟试题二
  10. IT接地系统工作原理
  11. 全国近三成高考状元被曝有加分(图)
  12. 【Red Team——基础】通过钓鱼攻击获得访问权限
  13. vim编辑器的简单使用(参考别人文章的学习笔记)
  14. 女子连WiFi结果收到巨额话费单:有些WiFi其实是收费的
  15. 大一计算机思维知识点,大学计算机基础教学中计算思维的培养途径
  16. 苹果手机微信端打开网页长按保存图片可以唤醒但是点击保存、发好友无效
  17. WiFi的2.4G、5G、6G频段
  18. 快速掌握SAP BDC数据导入
  19. matlab逐步积分,第17章 隐式逐步积分法.ppt
  20. 纳米器件,量子点理论文献拾遗

热门文章

  1. 做在线交易你必须知道的关于支付的知识
  2. win7系统修复工具_Windows Repair Pro v4.4.60 系统修复工具
  3. [JAVA学习] JDK与JRE的区别
  4. 计算机i网络管理员证书四级,软考网络管理员试题练习(4)
  5. kindle 3之安装多看系统
  6. 从0开始移植冒险岛online,和小伙伴一起在局域网或私服怀旧吧
  7. android 静默安装实现,Android 中静默安装实现详解
  8. 计算机学院毕业设计任务书,计算机专业毕业设计任务书.doc
  9. 二、 防火墙中使用的核心技术
  10. 什么是消息队列(Message queue)