点云平台之cloudCompare开发三
之前我写过关于cloudCompare开发的两篇博客,从访问量来看反响还算可以,该系列第一篇博文,从其它各个网站转载以及其它博主转载加上我本人的博客,网上可查的,这一年的访问量估计突破7000左右,日均差不多20人次的访问量。该系列的第二篇博文,目前我本人博客访问量2000+,其它转载访问量目前还没去统计。之前一直决定要停更的,因为工作以及我个人原因,一方面确实是很难有时间研究这些工具,工作中研究的一些方法与业务流程毕竟属于公司,虽然没有深度,但是本着职业道德精神我个人无法将其公之于众;另一方面琐事缠身,现在很难做到心如止水,波澜不惊,业余时间近乎完全被消磨掉,但是无力抗拒,人是群居性动物,所以随波逐流反而成为了最正常的生活方式。进入21世纪2.0时代这种无奈与失落感与日俱增。转眼间已到2020年,博主供职于现在的公司已差不多2年之久,虽然目前知识水平十分有限,但是还是想把这两年三维激光在测绘领域发展的一些所闻所见跟大家分享一下。三维激光行业其实与5年前相比已经火热不少了,5年前博主第一次接触三维激光时,那时三维激光主要面向文物保护行业,业务也主要偏向于体力活,很容易被复制取代,毕竟只是一个业务流程的问题,用什么仪器,怎么去作业,后处理用什么软件,经历哪些步骤,最后出什么结果。其实就是一套较为固定的流程,毕竟只是使用一些成熟的软件,并没有在一些难点上有所突破,最多就是把三维激光技术应用于文物保护而已。17下半年-18年年初步入工作以来,最开始的职责主要是研究一些点云处理的算法,2019年以来开始承担基于点云数据的矿山量测软件的设计与开发。目前三维激光应用的领域较多,并对传统测绘的作业模式提出了较大的挑战,像目前应用较多的电力巡线、林业、矿山、道路等等,并且许多新的领域也都在积极做这方面的尝试,未来不出意外的话,三维激光的应用面会越来越广,但是碍于技术不是特别成熟,软件研发难度较大,又属于刚刚兴起,软硬件遇到的技术瓶颈也较多,所以不可能爆发式的增长,况且测绘行业属于小众行业,国家扶持力度有限,所以也导致了它短期内不可能大热。
说这么多,其实就是希望跟我有相同学习背景的同学能对三维激光技术多点耐心,给它一点时间去证明,它代表着测绘领域发展的新方向,但是基于其目前发展的现状,也不能盲目自信,毕竟他还“小”,需要时间去成长。
以上纯属博主个人主观意见,由于知识水平有限或者存在一些凭空臆断、先入为主的因素,可能部分观点与事实相违背,还希望大家能谅解一下,有什么不同的意见欢迎大家私信探讨一下,相互学习,感激不尽。
之前该系列的两篇博文,是教大家如何在CC上加入自己的功能,今天这篇博客可能没有先前那么华丽,但是其意义丝毫不逊于前者,这篇博文博主旨在教大家学会如何利用CC的源码。其实前段时间移植CC相关功能时就想简单粗暴把它整个代码复制黏贴过来,然后各种改,缺什么给它补什么,其实最后你会发现,你就差把整个CC的平台都移植过来了。其实一开始特别苦恼,就觉得程序设计不是得讲究低耦合高类聚吗?CC怎么这么气人。当然时间紧迫,来不及因为个人的无知而愤怒与忧伤,所以开始转换思路,既然剥离不了,那就只能脚踏实地一点一点耐心的去研究其算法思想。通过几次成功的实践,我发现后者更靠谱点,其实对于算法而言,代码其实并不是那么重要,重要的是思想,譬如好多算法工程师就不会编程语言,会的可能就是matlab甚至是使用伪代码,但是在我个人看来这些都无伤大雅,重点是我只需要你给我提供一套完整且准确可行的数学公式足矣。即使成功抠出来别人平台里的代码,尤其是出现某些错误时,由于不理解逻辑以及其算法思想,最终也只能束手无策,仅仅只是拿来主义而已。什么是二次开发,它等于拿来主义,算法才属于真正的核心。
之前研究过CC的几个模块,涉及公司业务,这里不再赘述。这里以一个简单的例子加以描述,其实重点就看for循环,以及if判别条件,看对每一个数据点做了什么操作,这一点即为算法的核心。大家可以看看下图的红色对话框标注出来的文字,基本很好理解,就是对每一个数据点做如下操作,从第一个点开始判别其是否存在重复点,如果存在,标记这个重复数据点,后续遍历跳过标记的数据点。
以下一段代码,是本人在自己的平台上实现的一段代码,大家可以参考一下,代码写的较为简单,难度很小。
//移除重复的数据点 void tgd::removeDePlicatePts() { if (clouds) { int ptsNum = clouds->points.size(); int *dep = new int[ptsNum]; for (int i = 0; i < ptsNum;i++) { dep[i] = 0; } pcl::KdTreeFLANN<pcl::PointXYZRGB> kdtree; kdtree.setInputCloud(clouds); pcl::PointXYZRGB searchPoint; for (int i = 0; i < ptsNum; i++) { if (dep[i] ==0) { searchPoint = clouds->points[i]; vector<int>pointIdxNKNSearch;//存储查询点的近邻索引 vector<float>pointNKNSquareDistance;//存储距离的平 kdtree.radiusSearch(searchPoint, 0.000001, pointIdxNKNSearch, pointNKNSquareDistance); if (pointIdxNKNSearch.size() >= 2) { dep[pointIdxNKNSearch[1]] = 1; } } } PointCloud<PointXYZRGB>::Ptr result(new PointCloud<PointXYZRGB>); for (int i = 0; i < ptsNum; i++) { if (dep[i] == 0) { result->points.push_back(clouds->points[i]); } } createNewResult(result, QString::fromLocal8Bit("移除重复点"));
delete dep[];
}
else { cout << "点云数据不存在!!!" << endl; }
}
上面可能存在<br>建议大家直接忽略点,网页排版的问题,web前端里的换行符而已,博主当年自己学了一些web开发的知识,也曾经一度成为我的职业规划。
为了说明问题,博主把同一份点云数据进行了复制。