图片天空区域识别

本文介绍了一种用于自主导航系统的天空区域识别算法,并对该算法进行了改进。改进后的算法能更准确地识别出天空区域,尤其在弱纹理区域表现更好。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主介绍了一下一种天空区域识别的算法,参考论文: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 算法在硬件上不宜实施。







转载于:https://www.cnblogs.com/zhubaohua-bupt/p/7182824.html

### Python OpenCV 实现图像中天空区域检测与背景替换 对于识别图片中的天空部分并更换背景的任务,可以采用基于颜色空间转换、阈值分割以及形态学操作的方法。通过这些技术能够有效地分离出天空区域,并进一步应用蒙版完成背景的替换。 #### 颜色空间的选择 为了更好地提取天空的颜色特征,在HSV(Hue Saturation Value)色彩模型下工作通常会更有效果[^1]。因为在这个模式里,色调(H)代表了不同种类的颜色;饱和度(S)表示纯度;亮度(V),即明暗程度。相比于RGB,它更容易区分特定类型的物体比如蓝色或青色为主的天空。 ```python import cv2 as cv import numpy as np def detect_sky_and_replace_background(image_path, new_bg_color=(0, 255, 0)): image = cv.imread(image_path) hsv_image = cv.cvtColor(image, cv.COLOR_BGR2HSV) lower_blue = np.array([90, 50, 70]) upper_blue = np.array([128, 255, 255]) ``` 上述代码片段展示了如何读取一张图片并将BGR格式转化为HSV格式以便后续处理。定义了一个范围`lower_blue`到`upper_blue`用于捕捉大部分情况下属于蓝天的部分[^3]。 #### 创建掩码和填充新背景 一旦获得了合适的颜色区间,就可以创建一个二元掩码来标记哪些像素被认为是天空的一部分: ```python mask = cv.inRange(hsv_image, lower_blue, upper_blue) kernel = np.ones((5,5),np.uint8) opening = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel) result = image.copy() for i in range(3): result[:, :, i] = np.where(opening==255, new_bg_color[i], image[:,:,i]) cv.imwrite('output.jpg', result) ``` 这里先利用`inRange()`函数生成初步的掩码,再经过开运算去除噪声点得到更加平滑的结果。最后遍历每一个通道更新那些被判定为天空位置上的像素值为新的背景颜色。 #### 结合Tesseract进行文字保护 如果担心所选区域内可能存在重要文本信息,则可以在执行此过程之前调用pytesseract库来进行OCR扫描确认是否存在任何字符需要保留下来不受影响。 ```python try: from PIL import Image except ImportError: import Image import pytesseract text = pytesseract.image_to_string(Image.open(image_path)) print(f"Detected Text: {text}") ``` 这段脚本尝试导入PIL模块以支持更多文件类型的支持,并使用PyTesseract API获取给定路径下的图片中存在的可辨识字符串列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值