基于棱线配对的柱面识别策略

需求分析

为解决基于特征值特征向量的柱面识别策略不鲁棒的问题,本文在上周工作的基础上提出了一种基于棱线配对的柱面识别策略。

输入输出

  • 输入:局部可能包含柱面和椭球面的三维离散化网格
  • 输出:柱面的参数

识别策略

既然是基于棱线配对的柱面识别策略,那么首先我们需要获取棱线。在网格生成中,棱线是一个很重要的概念,它是由两个顶点组成的线段,而顶点是由三角形面共享的。因此,我们可以通过遍历所有的三角形面,获取所有的棱线。在此之后,需要对棱线进行几何意义上的分段与拟合,获取棱线局部的曲率半径及曲率中心,选择出属于局部圆形的棱线。在此之后,需要对识别出的圆进行剪枝,这一步比较依赖于经验,因为不同模型数量级和大小不同,剪枝策略下对应的阈值参数也不同。最后需要对剪枝后的圆进行参数化,并将各个圆形两两配对,得到最终的柱面参数。

棱线获取

设置宏定义`EDGE_INDEX’,通过遍历所有的边,根据其相邻面片法向量的差是否大于’EDGE_INDEX’来判断是否为棱线。

以下是一个代码示例,并非基于MeshLib的实现,仅供参考。

#define EDGE_INDEX 0.8

for (int i = 0; i < mesh->numEdges(); i++) {
    Edge *edge = mesh->edge(i);
    if (edge->isBoundary()) continue;
    Face *face1 = edge->halfedge(0)->face();
    Face *face2 = edge->halfedge(1)->face();
    if (face1 == NULL || face2 == NULL) continue;
    Vector3d normal1 = face1->normal();
    Vector3d normal2 = face2->normal();
    if (normal1.dot(normal2) < EDGE_INDEX) {
        edge->isEdgeLine = true;
    }
}

棱线拟合

对于识别出的棱线,我们需要对其进行拟合,获取其曲率半径及曲率中心,由于三点定圆,所以选择棱线上相互连续的三个点进行拟合,比较建议的选点策略是深度优先选择,可以尽可能的减少三点不共面的情况,三点不共面的情况会有但是实际上几乎不会影响到结果,毕竟很难找到对应的圆来与之配对。

以下是一个代码示例,并非基于MeshLib的实现,仅供参考。

for (int i = 0; i < mesh->numEdges(); i++) {
    Edge *edge = mesh->edge(i);
    if (!edge->isEdgeLine) continue;
    Vertex *v1 = edge->halfedge(0)->vertex();
    Vertex *v2 = edge->halfedge(1)->vertex();
    Vertex *v3 = edge->halfedge(0)->next()->vertex();
    Vector3d p1 = v1->position();
    Vector3d p2 = v2->position();
    Vector3d p3 = v3->position();
    Vector3d n1 = v1->normal();
    Vector3d n2 = v2->normal();
    Vector3d n3 = v3->normal();
    Vector3d center = getCircleCenter(p1, p2, p3);
    double radius = (p1 - center).norm();
    edge->circleCenter = center;
    edge->circleRadius = radius;
}

棱线剪枝

异常圆的剔除

剪枝主要去除的是棱线度不为2的点和半径过大的点,应该很好操作,这里不再赘述。

相近圆的合并

对于相近的圆,我们需要将其合并,这里的相近是指圆心距离小于一定阈值的圆,这个阈值是需要根据实际情况调整的,可以重载operator==来实现。

    struct circle
    {
        double radius;
        CPoint center;
        CPoint normal;
        
        bool operator== (const circle& c) {
            return abs(radius - c.radius) < ZERO && ((center - c.center).norm() < ZERO) && ((normal - c.normal).norm() < ZERO);
        }
        
        circle(double r,CPoint c,CPoint n):radius(r),center(c),normal(n){}
    };

棱线配对

对于剪枝后的圆,我们需要将其两两配对,得到最终的柱面参数。


void CirclePairRe<M>::getCirclePair()
    {

        for(int i = 0 ; i < circlelist.size() ; i++)
        {
            // if(circleIndex[i] < 2) continue;
            for(int j = i ; j < circlelist.size() ; j++)
            {
                // if(circleIndex[j] < 2) continue;
                if(abs(circlelist[i].radius - circlelist[j].radius) <ZERO && (circlelist[i].normal ^ circlelist[j].normal).norm() < ZERO && ((circlelist[i].center - circlelist[j].center)^circlelist[i].normal).norm() < ZERO ) 
                {
                    auto cylinderCenter = (circlelist[i].center + circlelist[j].center) / 2;
                    auto cylinderHeight = (circlelist[i].center - circlelist[j].center).norm();
                    if(cylinderHeight < ZERO) continue;
                    auto cylinderRadius = circlelist[i].radius;
                    auto centerline = (circlelist[i].center - circlelist[j].center);
                    centerline /= centerline.norm();
                    auto rotate = new Eigen::Matrix3d();
                    CPoint x(-centerline[1], centerline[0], 0);
                    x /= x.norm();
                    CPoint y = centerline ^ x;
                    *rotate << x[0], x[1], x[2],
                               y[0], y[1], y[2],
                               centerline[0], centerline[1], centerline[2];
                    cylinder *cc = new cylinder(cylinderRadius,cylinderHeight,cylinderCenter,rotate);
                    cylinderlist.push_back(*cc);
                }
            }

        }
    }

总结

棱线配对可以避免线性相关的问题,提高了柱面识别的鲁棒性,但是在实际应用中,这样的方法大幅依赖棱线,但工业上很多倒角都是光滑先借的,应用场景有限,但是对于一些特殊的模型,这样的方法还是很有意义的。
在这里插入图片描述

本博客由作者本人同步更新到本站,欢迎访问原文

内容概要:文章详细介绍了渤海大学首胜队参加第九届“飞思卡尔”杯全国大学生智能汽车竞赛的情况。该竞赛涵盖控制、模式识别、传感技术、电子、电气、计算机、机械等多个学科,旨在推动汽车智能化技术的发展。文中首先阐述了智能汽车的研究背景及其重要性,强调智能化是未来汽车发展的趋势。接着介绍了基于MK60DN512VLQ10微处理器的智能车设计方案,包括机械设计(悬挂、轮胎、舵机等)、电路设计(电源管理、电机驱动、红外检测、摄像头、编码器等)和动作设计(腾空飞跃、漂移过弯、走双边桥、过转盘、侧边行车、漂移入位)。文章还展示了系统框图,详细列出了各模块的功能和连接方式。最后总结了团队在整个项目中的收获,包括遇到的问题、解决方案以及团队协作的经验。 适合人群:对智能汽车竞赛感兴趣的学生和技术爱好者,尤其是参与类似竞赛或研究项目的人员。 使用场景及目标:①帮助读者了解智能汽车竞赛的具体流程和技术要求;②为准备参加此类竞赛的团队提供参考案例和技术支持;③展示如何将多学科知识融合应用于实际工程项目中。 其他说明:本文不仅提供了详细的硬件设计和软件编程指导,还分享了团队在比赛过程中积累的经验教训,强调了团队合作的重要性。此外,文章附有详细的参考文献列表,方便读者进一步查阅相关资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值