跳到主要内容
实操指南10 分钟阅读

把街景语义分割结果,变成经得起追问的指标

在朝向、类别体系、拍摄季节和校验方式确定下来之前,一个类别占比还算不上指标。这四件事,每一件都会改变那个数字。

作者
HuiTu Technology
发布时间
更新时间

把分割模型跑在街景影像上,是整件事里最容易的部分。开源的城市场景模型效果不错、跑得也快,而那张彩色输出图看上去足够有说服力,以至于人们会接受从另一端吐出来的任何百分比。

难的是从像素图到一个真会被拿去做决策的数字之间的全部环节。下面就按这些问题实际发作的顺序,把中间的决策逐一走一遍。

一个点,四个朝向,一份画像

单一相机朝向测量的不是这条街,而是相机恰好对着的那个方向。镜头朝着公园,这条街看起来绿意盎然;镜头沿着车行道望过去,同一个位置就变得光秃秃。

  • 每个采样点渲染 0°、90°、180°、270° 四张透视截图,逐张计算指标,再平均成该点的一份画像。
  • 整个项目的视场角必须固定。视场角一放大,天空和建筑顶部就被更多地纳入画面,你接下来要算的每一个占比都会随之偏移。
  • 俯仰角同样要固定,并保持接近水平。轻微向上仰是最快抬高天空占比、又最不容易被察觉的做法。
  • 推理之前先把全景重投影成平面透视截图。模型是在普通的直线透视照片上训练的,直接喂等距柱状全景,等于把弯曲的建筑和拉伸的天空塞给一个从没见过它们的网络。
  • 除了平均后的画像,也把四个朝向各自的值留下来。它们之间的离散程度能告诉你,这个点是落在一条形态确实均质的街道上,还是落在两种截然不同街道的交界处。
处理前的街景画面,包含建筑、车行道、车辆与行人
输入:推理之前的一张采样画面。后续所有指标,说的都只是这个视野范围内的情况,不多也不少。
同一张街景画面叠加语义分割结果,各区域按类别着色
输出:每个像素都被赋予一个类别。这一帧里的类别占比,就是绿视率、天空占比和围合度代理指标的原材料。

把指标定义精确

下面每个指标都是被分类像素的占比,这就使类别定义成了承重结构。请把定义写在数字旁边——两支团队各自计算绿视率,仅仅因为把哪些类别算作绿色不同,结果就能差好几个百分点。

指标、定义,以及各自对什么最敏感
指标定义最敏感的因素
绿视率植被像素占可见画面的比例,并在四个朝向上取平均拍摄月份,以及草地与地被是否被算作植被
天空占比天空像素占画面的比例相机俯仰角、视场角,以及晴天下的过曝
围合度代理竖向界面(建筑、围墙、栅栏)与可见天空之比树冠遮挡立面,会在夏季把这个比值压低
地面构成车行道、人行道与地被各自的占比路边停放车辆对车行道与路缘的遮挡
行人与车辆存在度检测计数,与像素占比并列报告拍摄时段与星期几,而这两者在平台影像里是无法控制的
import numpy as np

# Cityscapes evaluation ids, the label space most open urban-scene models emit.
ROAD, SIDEWALK, BUILDING, WALL, FENCE = 0, 1, 2, 3, 4
VEGETATION, TERRAIN, SKY, PERSON = 8, 9, 10, 11


def indicators(labels: np.ndarray) -> dict:
    """Class shares for one perspective crop, expressed as percentages."""
    total = labels.size

    def share(class_ids):
        return sum(int((labels == cid).sum()) for cid in class_ids) / total

    green = share([VEGETATION])          # trees and shrubs, not grass verges
    sky = share([SKY])
    vertical = share([BUILDING, WALL, FENCE])

    return {
        "green_view_pct": 100 * green,
        "sky_share_pct": 100 * sky,
        # Enclosure proxy: vertical surface against visible sky. Clamped so a
        # view with no sky at all cannot divide by zero.
        "enclosure_ratio": vertical / max(sky, 1e-3),
        "ground_pct": 100 * share([ROAD, SIDEWALK, TERRAIN]),
        "person_pct": 100 * share([PERSON]),
    }


def point_profile(crops: list[np.ndarray]) -> dict:
    """One profile per sample point: the mean across its four headings."""
    per_heading = [indicators(crop) for crop in crops]
    return {
        key: float(np.mean([heading[key] for heading in per_heading]))
        for key in per_heading[0]
    }

绿视率有一条值得在方法被质疑时援引的学术脉络:2015 年发表于《Urban Forestry & Urban Greening》的改进型绿视指数,以及 MIT Senseable City Lab 将其推广到多座城市的 Treepedia 项目。把自己的定义对齐到一个已发表的定义上,并且在交付时说明这一点,远比在评审会上为一个自创公式辩护来得省事。

Cityscapes 和 Mapillary Vistas 不能互换

无论你用哪个预训练模型,它的类别体系决定了你能测什么。城市场景领域占主导的这两套体系,差异大到在各自体系下算出的指标无法直接比较。

两套类别体系,两种用途
CityscapesMapillary Vistas
类别粒度一组紧凑的评测类别,覆盖常见城市场景体系大得多,在街道设施与路面标线内部有精细区分
采集背景欧洲城市的车载前挡风采集,基本是晴好天气的白天来自多个国家、多种相机、多种季节与天气的贡献者影像
植被处理植被与地被分属不同类别,草地与树冠不在一起植被与地面的划分更细,会改变「绿色」到底包含什么
更适合快速、生态成熟的基线,以及跨研究的可比性精细的资产与街道设施盘点,以及与德国街道毫不相像的影像
主要风险用于全景或非欧洲街景时存在域偏移体系复杂,必须事先自行定义聚合规则

混淆真正发生在哪里

  • 植被与地被之争:一条草坪带算不算绿色,在郊区街道上能让绿视率相差好几个百分点,在市中心则几乎没有影响。
  • 围墙、栅栏与建筑之争:对围合度而言这三者都是竖向界面,但如果模型把它们划分得前后不一致,围合度就会在本来平稳的地方显得很跳。
  • 人行道与车行道之争:路缘很细,又常被停放车辆遮挡,是不同模型之间最常见的分歧来源。
  • 骑行者与行人之争:一个骑车的人是算作一个行人,还是单列为骑行者,会直接影响任何街道活力指标。

季节与光照是系统性偏差,不是随机噪声

随机噪声会在大样本里被抹平,季节与光照效应不会:它们把所有在相同条件下拍摄的点,朝同一个方向推。这恰恰是那种能在聚合之后依然存活、并最终变成虚假结论的误差。

  1. 把拍摄月份一路带到最终结果表。它如果不是一列,季节性就是你所有对比中的一个隐藏变量。
  2. 绝不要拿落叶期与展叶期的影像去比较植被指标。影像年份混杂时,要么限定在可比的时间窗内,要么把月份显式建模进去。
  3. 留意阴天被读成明亮建筑立面的情况,以及高光溢出把细枝并入天空的情况。
  4. 低太阳角度的影像要单独检查。横跨车行道的长影会改变地面类别占比,并压低表观的活动计数。
  5. 把湿滑路面当作一种已知的失效模式:反射会把天空和建筑的像素铺到地面上。
  6. 按比较单元报告季节与光照构成,让读者能看出两个行政区究竟是不是在相近条件下被测量的。

用分层抽样做人工校验

任何指标在交付前都要经过人工核查,而这个核查必须是设计出来的,不能临时起意。挑几张看着有意思的图打分,得到的一致性数字没有任何意义。

  1. 跨行政区、跨拍摄月份、跨指标取值区间做分层抽样,确保绿意最浓和最光秃的街道都被覆盖,而不是全挤在中间段。
  2. 用固定的点阵网格逐张人工打分——用肉眼对规则排布的采样点逐点判类,无需全图标注就能得到一个可复现的参考占比。
  3. 一致性要以分布形式报告,而不是一个平均值:既给平均绝对偏差,也给最差的那几例,系统性问题就藏在那里。
  4. 逐个检查分歧样本。它们会成簇出现,而这一簇通常直接指明了失效原因:阴影、反光、不常见的立面材质、陌生的车辆类型。
  5. 只要模型、类别体系、视场角或影像来源发生变化,就要重新校验。这四项中的任何一项,都会让此前的一致性数字失效。
  6. 校验结果随数据一并交付,注明样本量与方法,而不是用笼统的措辞描述精度。

这次校验最终回答的是:这条流水线对当前决策是否足够精确。不要给出脱离项目的统一精度承诺,而要报告这批影像、这个模型和这组样本实际测得的误差分布。结果可能足以支持街道排序,却仍不足以把单个点位当作真值——这个区分应在交付前写清楚,否则总会有人把一个精确到两位小数的数字原样引回规划会上。

更多文章

继续阅读

下一步

比起了解方法,更想直接把事做完?

如果文章里描述的问题正好是你遇到的,把具体情况发来,我们会给出工作范围与固定报价。