平行轮廓填充代码_2020年国赛B题_接触式轮廓仪的自动标注

题目来源:2020年全国大学生数学建模竞赛D题

欢迎关注公众号《数模派》,可获取更多信息~

商业合作:QQ:1559601632

有一段时间没有更新了。最近在做些其它事。之前有人和我说国赛的D题和E题是给专科组的,于是小编这次做了下2020年国赛D题(下文简称D题)。这个题的难易程度很适合专科生。如果是本科组的题,那么略显简单。就D题的解题思路来说,问题的关键是如何找出所给数据中的轮廓的位置,这需要参赛队员或者指导老师需要了解一些数字图像处理的知识。这里涉及到的主要有:角点检测、霍夫变换、仿射变换。对于以上算法,由于篇幅的原因,小编就不在这里详细介绍了。读者感兴趣的话,可以自行百度。

和数字图像处理不同的是,所给的数据是序列数据,而不是图像。因此,我们有两种思路来解这个题:(1)先把序列数据已散点图的形式可视化,转为图像;然后对图像来做角点检测、霍夫变换、仿射变换;(2)直接用角点检测、霍夫变换、仿射变换操作序列数据。角点检测是用来检测两条直线的交点的。霍夫变换是用来检测直线的,即弧+直线、人字形线。仿射变换是用来校正发生旋转、平移过程的数据的,也就是题目的第二问。方法1不需要自己写角点检测、霍夫变换、仿射变换的代码,直接调用opencv中的相关函数即可。方法2则需要自己写相关的代码。小编使用的是方法2。

1. 轮廓分割

使用角点检测进行轮廓分割,实际上就是找出线段之间的交点。图1为角点检测的结果,其效果很好,所有的角点(图中灰色点)都检测出来了。

ea635d47e67e7a0ffe21d08dc62171eb.png
图1 角点检测结果

当然,还有另一种方法来实现轮廓分割。分割轮廓,其实质就是计算曲线的波峰、波谷。这是一个 TopN 问题。我们只需要维护一个N 个大小的数组,初始化放入N Query,按照每个Query的统计次数由大到小排序,然后遍历所有记录,每读一条记录就和数组最后一个Query对比,遍历。以上过程可以直接使用python中的heapq包里的方法,heapq.nlargest(n) 计算最大值,既是波峰;heapq.nsmallest(n) 计算最小值,既是波谷。图2为该方法的结果,其效果令人很满意。对于图中最后一部分水平线段,程序认为它也是波谷了。这是因为原数据偏差较大导致的,我们把它手动去除即可。

dcbbd71c4dc629591728062c9c9fb1ad.png
图2 分割波峰波谷

图2 分割波峰波谷

2. 轮廓参数标注

轮廓总共有三种,线段、弧、线段+弧。如果是发表论文,那么我们用霍夫变换来检测线段。虽然霍夫变换可以检测圆,但小编没有搜到用来检测弧的示例。直接检测弧较为困难。对于比赛来说,这是既耗时又耗力的,得不偿失。因此,对于人字形和单个弧,我们根据波峰和波谷出现的次序来人工识别轮廓。对于线段+弧,我们需要画出它的子图,然后大约估计一下线段和弧的交点位置,以此来分割它。得到轮廓后,计算线段之间的夹角,线段长度,槽口宽度,弧的半径、圆心、弧长,这些都很容易了。

3. 校正

我们采用仿射变换来实现图像校正。仿射变换,就是经过平移、旋转、缩放或者这些操作的组合来改变图像。这是一种线性变换,其结果是,原来互为平行线的直线,进过变换后,依旧是平行线,但是它们的长度可能发生改变。变化前和变化后的坐标满足以下关系:

其中,

,
是变化前的坐标,
,
是变化后的坐标,是
要求的参数。由此可见,我们拟合两个线性方程即可得到校正的方程。这里需要注意的是,所给的变化前和变化后的数据个数相等。小编直接按它们的最小值从前往后截取了。校正的结果如图3所示。对于变化前后的倾斜角度,我们只需要从两组数据中找同一点,计算下它们夹角即可。当然,你也可以把全部的点都计算了,然后求其均值。

2e871cf6b71c588517f4b8ebf42a9df6.png
图3 校正后的结果

本次分享就结束了,不出意外的话,下次该更新2020年国赛的B题啦~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值