【2021 亚太赛】A题-Image Edge Analysis and application图像边缘分析与应用 参赛经历与思路与实现讲解
前言
以下为我的真实的做题过程,按照我下面说的做,绝对可以复现出来。 这次亚太赛本人带了了本科的学弟学妹,纯小白的那种,而且中途一名学弟因为开题报告出问题不能继续参赛。
比赛经历
这个是比赛经历,仅仅是为了纪念一下哈,大家可以选择性略过。直接看下一部分
第一天(星期四)
因为比赛只有4天,第一天由于有英语演讲和数据挖掘考试,前一天几乎通宵复习了一晚上,第一天我就没有参与到比赛中,学妹她们看完题决定选A,正好咱们数学建模课大作业也是亚太赛题目,我就同意了他们的选择,正好也做完建模这个我也可以提交大作业,岂不是两全其美,妙啊妙啊~.~ 哈哈哈哈哈,后来开始做题的时候我就后悔了,不知道为啥他们认为A题简单。55555~~~
第二天(星期五)
早上8点-凌晨3点 今天几乎是啥也没做出来的一天,就用opencv和python、用canny能提取像素级别的边缘轮廓。而且用VScode编译程序的时候还经常卡死。提取的效果也不好,之后想到对图像进行预处理,但是处理结果也达不到我想要的,这时候已经第三天的凌晨3点了,我们第一问的进度还没有做完,之后我就用了PS对图像进行了处理,之后检测的效果还挺好的,第一问勉强做完了三分之一的进度把。这时候的我觉得我已经把学弟学妹她们给坑惨了,就让他们赶紧找相关资料先把论文框架写好,所以这次的论文与实践部分可能会对不上哈(大家参加过建模竞赛的同学dddd),就不给大家看我们的论文了,希望理解一下哈哈哈,轻喷(doge)
第三天(星期六)
早上8点-凌晨3.30 睡了大概4小时,8点躲起来接着搞,打算第一问先跳过了,看看第二问,继续找资料,突然发现了我的好朋友,也就是一会会给大家推荐的一个博主,这里就叫m哥吧。也在做这个题,之后我就请教了一波哈哈哈哈。 ![Alt] 这次比赛m哥的队友出了一些问题,之后没时间写论文了,他已经实现了一部分,之后就把思路分享到了网上。 通过m哥的指导,我开始学习Halcon,发现用这个做题真的是很方便,但是我可不是白嫖党啊,我也是知识付费了的(滑稽)其实等于白嫖了哈哈哈哈。 后来我就辅助m哥一起来做这个题,形势开始慢慢的好起来了,逐渐看到了希望。
m哥也在好奇,为什么我图像噪声去除的这么完美,哈哈哈哈,美术建模大赛。。。 image.png
我让学弟学妹她们赶紧去写论文, 时间是真的来不及了,下午建模课(请假了)逃了,其实是可以最后一节课去的,但是真的舍不得这一小时的时间。将近下课的时候,微信收到了消息轰炸,好多人都告诉我点名了,让我赶紧去,但是我真的是去不了。但这份同学情谊情谊我记下了(属实感动)。 一转眼就又第二天凌晨3点多了,不干了睡觉了。
第四天(星期日)
早上7点-第二天早上9点40 这时候,我发现我理解错题了,用第三问的难度去做第一题了。其实第一题只要提取出轮廓就完事了,我一直以为也要计算第一题中轮廓的基元数据,基元就是直线段、圆弧、椭圆弧啥的。真是又开心又觉得自己傻x了,纠结了这么久原来早就做完了。 接下来就是第三问,第三问我们遇到的问题就是,怎么把亚像素的坐标点转为Halcon里的Edges(轮廓数据),经过不断地努力,最后找到了算子。还是因为时间太短了,这个软件学的不精。最后为了避免数据和网上的重复,我对代码进行了微调,之后第一问的第二张图就检测出5个轮廓,还发现了一个坐标值顺序的问题,也发现了第二问存在的问题。第三问需要的直线数据可以全部导出,但是圆弧的数据却缺少条件,其实应该也有办法,但是太累了,脑袋已经不转了。因为第三问的轮廓还比较规则,这时候大概是下午还是晚上,我叫来了我的室友,进行手动提取坐标。放到excel里,进行系列运算,最后把表格填完了。 这时候已经快晚上12点了,论文的中文版还没有写完,我发现论文的写作有点偏题了,就又整理了一下简单的解题思路,对论文进行修改。最后论文是凌晨4点写完的,开始进行翻译。直接丢进翻译软件全文翻译了,之后拿出来逐句校对。因为本科生会断电,他们的电脑都用没电了,我让学妹他们先休息一下,我进行简单的排版。这时候模型假设、公式、图片、表格都没整理,参考文献也没加。 早上6点多,我在等翻译稿进行最终的排版,和校对。这时候我发现了一个严重的问题,就是学妹她们睡!着!了!!!!!
还好最后我叫醒了他们,虚惊一场。 8点59分47秒,论文勉勉强强排了个版,附件打包,交上去了。奥利给,真的极限。可惜的是支撑材料没交上。 这时候发了一个朋友圈,还收到了辅导员老师的关怀 以上就是这次比赛的个人经历,有做完的小伙伴我们也可以一起交流下哈,因为我之前也从来没有接触过图像处理,接下来会给大家描述大致的步骤,做的这个仅供大家参考,还有许多问题待完善。 具体参考请转到我朋友写的这个博客,资料、代码什么的都有,内容十分详细: https://blog.csdn.net/weixin_43935696/article/details/121555038?spm=1001.2014.3001.5501
我对上述的内容进行更简单的归纳梳理与勘误,加上了自己的个人理解。大家按照我这么做肯定能解决这个问题,如果有什么困难可以给我留言,我看到了就会帮大家一一解答。
用到的东西
- Python (主要用于数据处理)
- opencv(这个后来不用了)/Halcon(这个是主要的软件)
- Photoshop(看到这个大家是不是想打人)
- Excel(计算第一题,还有填写问题中的表格)
- 记事本(打开第一问第3小问导出的坐标数据)
问题一
问题分析:
解决过程
首先进行图像的边缘检测,第一次用的是opencv,用的是canny算法,检测效果大致如下。 大家可以发现图1-1是可以检测出来的,但是图1-2就玩球了,图1-3更是惨不忍睹,基本噪声都给检测出来了。 所以要对图像进行预处理 预处理的过程大概有这么多:
- 图像增强
- 图像平滑
- 图像二值化
- 之后进行锐化等xxxx系列的形态学处理
上述技术大家可以自行查阅资料,我也在参考文献里给大家提供了一些,都用红框圈出来了,方便大家查找 ?
经过处理之后,大家可以看到检测的效果就非常可以了 (其实预处理之后也不理想,上文也说了,我用了ps预处理,预处理一天还不如我ps半小时的效果好)
这个时候可以看到图1-2有五个轮廓,1-3有2个轮廓 那么题目里要实现的是亚像素级别的检测。为啥要用亚像素,这个是看的一点文献里说的为啥要用亚像素。 这个都给大家整理好了,在文件夹里都能找到,都标记了一下。 我的理解就是下面这个意思。
大家看,a,b两条轮廓都过了像素1、2、3,在像素级别下,他们就被当成一条线了,但是当我们想要更高精度的时候,就需要转化为亚像素了。 亚像素一般可以分为3个方法,分别是: 基于矩的方法、拟合方法(最小二乘法)、插值的方法。(这个大家写论文的时候想用啥就用啥吧) 这里用的是Halcon里面的亚像素检测的方法,这个算子是edges_sub_pix(),具体参数设置大家可以看官方文档,先不说了,有时间再整理一波。
这里我选用的是canny算子和lanser2算子 可以看到边缘已经被检测出来了,那么我们就要回答问题了 对问题进一步归纳:
- 计算边缘的长度
- 计算过的像素点
- 之后图1和图2的需要把轮廓的坐标导出来
这里有小伙伴可能有疑问,什么是过的像素点,什么是长度 我理解的是这样的 a这条线过的像素点是3个,但是长度却不是3
我们可以通过Halcon带的分析工具轻松的得到边缘长度和过像素点的个数 选择轮廓——点击打开特征检测——选择xld_contlength和xld_area_points 下面是我的数据,这个会发给大家,文件命名是第一问实现过程。1、2、3的大家都可以拿去参考一下
之后单独保存坐标数据,我朋友写的是用Python,我这里用的excel处理的,因为时间不够了,Python代码当时没调好hhh 下面我说说excel的简单处理思路(这里就文字描述了) 以为提取出来的是起始点的x1和y1。终止点的x2和y2的数据。所以大家只需要给这四个值变成(x1,y1)和(x2.y2)的形式。其实就是两边加一个括号和中间加个逗号。 **这里要注意啊!!!!**图像坐标是这么定义的,左上角是原点(0,0),见下图
这里更要注意啊!!!,Halcon里的坐标col对应的题目里的x坐标,row对应的是y坐标。之后坐标显示是(row,col),如下图
A点的坐标显示是(4,10),是先显示列,再显示行,有点反人类,可能是能调整但是我没找到。 到此问题一就over了。
问题二
问题分析
解决过程
同第一问,边缘检测效果如下 这里说一下代码里存在的问题,看这个最大的红色框框,之前算多了,把外框加进去了,当时程序的裁剪处理没调好参数,实际值应该是在这个左右的 标定板这里我就不说了,大家可以去看m哥的文档。简单描述为 求出两个圆心之间的dx,代码直接运行你就可以找到这个变量了,之后我们用下面的公式计算实际尺寸,解释一下:因为题目里说圆心距是2mm,所以找到有几个2mm就行了。 xi就是上表格中的像素长度值,第一问告诉大家怎么看了,dx就是程序里跑出来的,y_i就是我们要的实际尺寸。 再补充一下dx是啥: 这里我的dx就是代码里的distance/12,distance是上图两个红色圆圈之间的圆心距离 okk,表格填完,问题二解决!!
问题三
问题分析
之前问题一是从图像中直接提取出来的轮廓数据,之后把轮廓的坐标导出来 这个题,反过来了。他把第一问中的第三小问题的亚像素坐标数据给咱们了,之后我们得想办法给它转换成轮廓数据 之后再对轮廓进行切割,之后再检测出来每个基元(直线、圆弧、椭圆弧)
实现过程
通过Halcon里面的gen_contour_polygon_xld算子,我们可以把坐标数据转为轮廓数据 之后用segment_contours_xld算子,可以把轮廓分割为直线、圆弧、椭圆弧。 最后用fit_line_contour_xld拟合直线、fit_circle_contour_xld拟合圆。 之后我们就可以得到他们的具体值了 这里直线我们可以得到起点坐标的x,y;终点坐标的x,y 圆弧的圆心坐标x,y;半径长度;圆弧开始的扫描角;圆弧结束的扫描角度 ?
直线的问题就很简单了。我们只要知道起点坐标和终点坐标,就可以得到题目要求的所有属性 圆的问题,圆心可以得到了,之后扫描角度可以用:(圆弧开始的扫描角-圆弧结束的扫描角度)*180/π计算得到,它的方向是从x轴正向到y轴正向为正的。如下: 但是这里我遇到了一个问题,不知道怎么计算起点坐标和终点坐标 所以用了一个最原始的办法,就是去图里一个一个找,先把数据搞出来再说!!! 这步大家最好两个人做,这里要表扬一下本次被叫来打工的童鞋,我的室友一波
终于把表都填好啦!!!! 第三问勉勉强强Over
其实应该是不用这么搞的,但是连续干了27个小时,我的脑袋已经不转了,有机会再给大家提供计算方法吧,欢迎各位小伙伴一起探讨哈。
遇到的问题
解决了的
- 图像预处理
- 怎么导出坐标数据
- 怎么把坐标数据转换为轮廓数据
没解决的
- 图像预处理(你说解决了吧,它其实还没解决。用ps解决了,但是显然不行)
- 第三问,分割之后,进行拟合,会发现有许多短的圆弧被检测为直线段了,例如这下面的白色小段,其实是圆弧,但是却拟合为直线了。
- 时间问题,只检测了圆弧,没有椭圆弧,有了初步的思路,但是时间不允许,如果解决椭圆弧,那么上边的问题就解决了
- 我们采用的算子只能检测直线和圆弧、直线和椭圆弧,并没有直线+圆弧+椭圆弧这个操作,如果大家有兴趣可以一起沟通一下,应该是没找到这个功能。
小结
这个就是我的真实解题过程了,有很多地方因为知识欠缺,能力不够,走了捷径。有研究这方面的大佬看到了请忽略哈哈哈哈,当然如果可以帮我讲讲办法更好了。 喜欢搞数模和大数据竞赛的童鞋也可以加个联系方式 微信:Lm1572339155 ? 最后小明祝大家期末顺利,都别挂科奥! ps:有数理统计学会的大佬么,捞捞孩子吧,呜呜呜呜5555,一道题都听不懂啊
声明一点:我们不是代做哈,我学弟学妹参加的比赛,我去帮忙的。之后我朋友是因为队友跑路了,之后才把东西放在网上了。大家喜欢这方面比赛的可以关注一下他的csdn,里面有很多资料的。 ?
?
?
?
|