本文主介绍了一下一种天空区域识别的算法,参考论文:Sky Region Detection in a Single Image for Autonomous Ground Robot Navigation
顺便贴出对论文中算法稍加改进后,图片天空区域的识别效果图。具体怎么改进的见下面描述。
本文分为四个部分,依次是
一 天空识别的重要性
二 参考论文中的方法描述
三 自己的改进
四 实现效果对比
五 算法仍存在的问题
废话不多说,直接进入主题。
一 为什么天空区域识别很重要?
目前,智能机器人,自动驾驶汽车以及智能无人机等等逐渐走入人们的生活。这些智能设备都需要自主导航,而导航就离不开对周围环境的感知。
感知周围环境的距离是感知周围环境的重要一环,所以说感知周围环境距离很重要。人们常用传感器进行测距,在自主导航领域常见测距传感器有两类:第一类是主动式传感器,比如雷达,激光传感器,这类传感器比较精确,但缺点是比较贵;第二类是被动式传感器,比如视觉传感器。这类传感器成本较低,主要依赖于算法,但有些场景精度不好。但随着技术的发展,这些精度问题都可以得到解决。
我们今天所讲的天空区域识别是属于视觉传感器的一类中的算法。常见的视觉传感器,比如双目传感器,由于匹配测距原理的缺陷,对弱纹理区域无法准确识别。在室外,天空区域正是弱纹理区域的典型代表。因而,识别出天空在我们自主导航中的作用不言而喻。
二 参考论文中的方法描述
首先,算法假设:
<1>,真实的地面区域的平均亮度要比天空的平均亮度暗。
<2>,天空区域在图像上侧,地面区域在图像下侧。
<3>,天空区域比较平滑。
所以此算法还是有局限性的。
此算法的整体思想是:每一列图像上方往下扫描,通过不断的调整梯度阈值,得到不同的边界。然后,通过计算所有边界的能量函数来得到最优边界,最后再做优化。
step1,每给梯度设一个阈值,整幅图从按列从上往下扫描,得到一个边界。
step2,定义一个能量函数,每次得到一个边界后,图像上的区域可以被分成天空S和地面G区域。
当能量函数最大时,此时天空集合内和地面集合内的像素相似度最高。此时的边界被称为临时最优边界。
step3,如果临时最优边界跳变过大,就认为天空区域误检,需要把天空区域的像素用K-means分成两类,此时图片中有三个集合:两类天空(s1,s2)和地面G。根据两类天空(s1,s2)分别与地面G的马氏距离,把马氏距离大的认为是真实天空区域。(比如这里s1是真实天空)
step4,把S里的每一个像素分别与s1和G计算马氏距离,
若与s1距离近,则认为是天空像素,
若与G距离近,则认为是地面像素。
step5 , 以S的每一列为扫描单位,当这一列中天空像素不到一半,就认为这一列是误检,属于最终地面。当天空像素大于一半时,则认为这一列都是天空,属于最终天空。
三 自己对上述方法的改进
step1,每给梯度设一个阈值,整幅图从按列从上往下扫描,得到一个边界。
step2,定义一个能量函数,每次得到一个边界后,图像上的区域可以被分成天空S和地面G区域。
当能量函数最大时,此时天空集合内和地面集合内的像素相似度最高。
step3,由于每次扫描时,边界是由一个梯度阈值分割的,这肯定是不合理的,所以天空区域必定包含杂志(地面区域像素),所以对天空区域聚类,聚成两类,称为s1,s2,此时图片中有三个集合:两类天空(s1,s2)和地面G。
step4,判别s1与s2哪个是真实天空区域:论文中直接根据两类天空(s1,s2)分别与地面G的马氏距离,把马氏距离大的认为是真实天空区域(Strue),剩余的是地面区域。比如这里s1和地面G马氏距离比较大,则s1是真实天空区域,s2和G是地面区域。
step5,识别其他区域的天空:由于上述方法只能识别图片最上面的天空,即Strue,即如果图片中,天空被一道横着的电线挡住,则电线下面的天空就识别不出,所以对论文算法加以改进。改进的方法是:首先我们对图片其他区域(step4处理后的s2和G)的每个像素进行扫描,如果其他区域的像素满足以下两个条件则认为也是天空:
<1> 弱纹理区域
<2> 像素值和Strue区域的平均像素值 相差很小。
四 实现效果对比
每组图片有三幅图,依次是step3输出的聚类结果(s1和s2)、论文中方法的效果、改进后的效果
第一组:
第二组:
第三组:
第四组:
五 算法仍存在的问题
1 天空区域不在图片正上方不能识别。
2 图片从第一行开始有大量灰度值比天空还大的区域时容易误识别,因为分不清谁是天空。
3 算法在硬件上不宜实施。