实现简易避障(附C++源码):opencv提取语义分割后的图像区域质心

前言

似乎很久没有写博客了……所以赶紧写个博客冒冒泡,也顺便压压惊。最近导师让我使用realsense深度摄像头做android端的避障功能,首先,遍历图像中所有深度数据并进行过滤似乎是比较需要大量的计算量,在查找了一些资料之后,因为项目也用到了语义分割功能,何不使用语义分割后的图像进行轮廓、区域、质心提取,再计算质心坐标的深度值来进行避障呢?

说干就干,由于语义分割是在android端采集的,采用了deeplabv3算法,其中该算法工程参考:
https://github.com/wonderit/indoor-segmentation-android

处理图像使用opencv就行了,由于移动端相对来说比较麻烦,还要移植opencv,所以我先把deeplab获得的分割图像存入电脑,在电脑端使用C++和opencv对其进行处理,得到最后的质心。

获取语义分割图

下图是未经处理的rgb图:
在这里插入图片描述
下图是经过deeplab算法得到的语义分割图,可以看到不同的颜色代表着不同的东西,其中暗红色代表地面,灰色代表墙,深灰色代表凳腿右下角的箱子,紫色代表凳子,要进行避障,就得把这些区域的质心提取出来。
在这里插入图片描述

边缘覆盖一层矩形像素

要确保能够提取出每一块区域的质心,首先要保证各个颜色区域能够提取出来,而区域是闭合的,所以必须先在图像的边缘覆盖一层像素(矩形框),如下:在头像边缘覆盖了黄色矩形框。
在这里插入图片描述

转灰度图&提取轮廓

下一步就是将图像变成灰度图了,那么这里有个问题,就是如果覆盖的颜色和分割图像的某种颜色块相近的话,灰度图的颜色就比较难区分,进而在后面提取不出轮廓。如下:
在这里插入图片描述
可以看到箭头处灰度颜色相近,会导致后面提取轮廓提取不出。如下:可以看到右上角的轮廓直接被没有提取出来。在这里插入图片描述

这个问题的话我还没有想到好的解决方法,唯一的方法就是改变deeplab的物体颜色, 使我预设的覆盖颜色与分割图像的颜色大不相同,这样就可以解决这个问题了,但是我现在还没有去做这个事情。

改进版查找轮廓

在上图,我们也可以看到区域的线条很细,有一些轮廓根本就不是封闭的,也就无法构成一个区域,进而无法提取质心。所以在转灰度图–》提取边缘-》查找轮廓之后,我使用粗线条重新画出一个新的轮廓,再转灰度图,再查找一次轮廓,即可得到闭合的区域。

最终得到的区域图如下:可以看到区域都是闭合的,这样就可以愉快的求质心啦~
在这里插入图片描述

求质心

最后的结果如下:
是不是觉得还可以呢?知道各个物体的区域障碍物,就可以根据求得的坐标使用深度摄像头获取深度图来达到测距的作用,进而设置阈值做出相应的操作。
在这里插入图片描述

质心的非极大值抑制

看上图,右侧有两个质心的坐标太相近,检测两个点的深度是多余的,这时候我们可以使用非极大值抑制算法,使得两个或多个相近的质心点只取一个,且该点相较于其他点来说面积最大。
最后的结果如下图:可以看到,右侧面积较小的点已经被去掉了。
在这里插入图片描述

流程总结

总体流程:
得到语义分割图-->边缘加矩形-->转灰度图-->提取边缘-->查找轮廓-->
用粗线画轮廓-->转灰度图-->再查找一次轮廓-->得到各个区域重心-->非极大值抑制过滤相近点

在这里插入图片描述

得到质心的坐标,就可以使用深度摄像头愉快地测距,从而达到避障的效果啦!

源码地址

好了,终于要到贡献代码的时候了,我是在Ubuntu18下使用Kdevelop下跑的,小伙伴们可下载亲自尝试,欢迎有问题向我提问。

源码地址:
https://github.com/Hectoor/Contour-and-Centroid

发布了42 篇原创文章 · 获赞 39 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/Hanghang_/article/details/100835372
今日推荐