You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

航拍图像车辆检测:如何排除阴影避免其被纳入最小外接矩形?

解决航拍车辆检测中阴影干扰的实用方案

嘿,这个阴影误检的问题我在做停车场智能监测时也踩过坑!结合你用scikit-image做差分检测的方案,给你几个实际可落地的思路,帮你把阴影从检测结果里排除掉:

1. 颜色空间转换分离阴影

阴影的本质是亮度降低但色度不变,这是区分它和车辆的关键。你可以把图像转换到对光照变化更鲁棒的颜色空间(比如YCrCb或HSV),然后通过通道阈值来提取阴影区域:

  • YCrCb空间中,阴影的Y通道(亮度)远低于正常地面,但Cr/Cb通道(色度)和背景地面几乎一致;
  • 先从空停车场图像中计算背景的Cr/Cb均值,再在差值图中筛选出「Y通道低于阈值+Cr/Cb与背景差值小」的区域,就是阴影。

示例代码(基于scikit-image):

from skimage import color, filters, morphology
import numpy as np

# 假设diff_image是你计算出的空停车场与有车图像的差值图(RGB格式)
# 转换为YCrCb颜色空间
ycrcb_diff = color.rgb2ycrcb(diff_image)
y_channel = ycrcb_diff[:, :, 0]
cr_channel = ycrcb_diff[:, :, 1]
cb_channel = ycrcb_diff[:, :, 2]

# 从空停车场图像(background_img)提取背景的Cr/Cb均值
ycrcb_bg = color.rgb2ycrcb(background_img)
bg_cr_mean = np.mean(ycrcb_bg[:, :, 1])
bg_cb_mean = np.mean(ycrcb_bg[:, :, 2])

# 生成阴影掩码:亮度低+色度接近背景
y_thresh = filters.threshold_otsu(y_channel)
shadow_mask = (y_channel < y_thresh) & \
              (np.abs(cr_channel - bg_cr_mean) < 25) & \
              (np.abs(cb_channel - bg_cb_mean) < 25)

# 从差值图中移除阴影区域
diff_no_shadow = diff_image.copy()
diff_no_shadow[shadow_mask] = 0

2. 纹理特征区分车辆与阴影

车辆表面有明显的纹理(比如车窗、车身线条),而阴影区域的纹理更平滑单一。你可以用scikit-image的纹理分析工具,提取候选区域的特征后过滤掉阴影:

  • 用**局部二值模式(LBP)**计算区域的纹理复杂度,阴影的LBP特征值会更集中;
  • 或者用**灰度共生矩阵(GLCM)**提取对比度、能量等特征,车辆的对比度远高于阴影。

举个LBP的简单应用:

from skimage.feature import local_binary_pattern

# 对差值图的灰度版计算LBP
gray_diff = color.rgb2gray(diff_image)
lbp = local_binary_pattern(gray_diff, P=8, R=1, method='uniform')
# 计算每个区域的LBP方差,方差小的是平滑的阴影区域
# 结合区域props筛选:比如方差低于某个阈值的区域标记为阴影

3. 形态学+区域特征后处理

即使有漏网的阴影,也可以通过形态学操作和区域属性筛选来排除:

  • 用skimage.morphology.remove_small_objects()去掉面积过小的细碎阴影;
  • 用skimage.measure.regionprops()计算每个候选区域的长宽比、面积、矩形度等特征,阴影通常更扁长,而车辆的长宽比更接近固定范围(比如1:2到2:1之间)。

示例:

from skimage.measure import label, regionprops
from skimage.morphology import remove_small_objects

# 二值化差值图(先处理掉阴影后的图)
binary_diff = color.rgb2gray(diff_no_shadow) > filters.threshold_otsu(color.rgb2gray(diff_no_shadow))

# 移除小物体
binary_clean = remove_small_objects(binary_diff, min_size=500) # 阈值根据你的图像调整

# 标记区域并筛选
label_img = label(binary_clean)
for region in regionprops(label_img):
    # 过滤长宽比不符合车辆的区域(比如阴影可能长宽比>5)
    if region.major_axis_length / region.minor_axis_length > 5:
        label_img[label_img == region.label] = 0

4. 多帧时间差分(如果有连续航拍帧)

如果你的航拍是连续帧序列,阴影的位置和形态变化很慢(甚至不变),而车辆是移动的。可以通过多帧差分的交集来过滤:

  • 计算连续3-5帧的差值图,只保留在多帧中都出现的区域(车辆),排除只在单帧或少数帧出现的阴影(如果光照有变化);
  • 或者取多帧差值的并集,然后排除持续存在的区域(阴影)。

这些方法可以组合使用,比如先通过颜色空间过滤大部分阴影,再用纹理+区域特征做二次筛选,基本就能解决大部分阴影干扰的问题了!

内容的提问来源于stack exchange,提问作者nipunasudha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:22:25