Colab正常运行但高校Jupyter平台报错:栅格化U-Net语义分割标签时出现颜色数量不匹配ValueError
我在Google Colab中运行以下代码,将Shapefile栅格化以生成U-Net语义分割的标签,代码运行正常,栅格化后的Ground Truth也能正常绘制:
rstzr = r.Rasterizer(shape_file, raster_file, class_column, classes_interest = classes_of_interest, non_class_name = non_class) rstzr.collect_class_names() rstzr.rasterize_layer() rstzr.remove_labels_under_cloud(pos_qa = 0, new_label = 3) m_class_names = ['No Data'] + rstzr.get_class_names() + ['Clouds'] rasterized_layer = rstzr.get_labeled_raster() rstzr.save_labeled_raster_to_gtiff(out_labels) vis.plot_labels(rasterized_layer, m_class_names, colors = ['white', 'green', 'yellow', 'blue'], title = "Rasterized Ground Truth")
但在我校的高性能计算Jupyter平台运行完全相同的代码时,却抛出了如下错误:ValueError: There are 5 color bins including extensions, but ncolors = 4; ncolors must equal or exceed the number of bins
可能的原因分析
环境依赖版本差异
两个平台中vis.plot_labels函数(或其依赖的可视化库,比如matplotlib、rasterio等)的实现或版本不一致是最可能的原因。Colab中的版本可能会自动处理颜色数量不足的情况(比如重复使用颜色或自动补全),而高校平台的版本则严格要求颜色数量必须匹配所有需要渲染的bin数(包括所谓的"extensions"——可能是函数自动添加的边界、额外辅助类别等)。实际标签类别数量不一致
虽然代码中m_class_names看起来是4个类别(['No Data'] + 2个目标类别 + ['Clouds']),但在高校平台中,可能存在以下情况导致实际标签数变多:rstzr.get_class_names()返回的类别数量和Colab中不同(比如Shapefile读取时的编码、过滤逻辑差异)rstzr.remove_labels_under_cloud操作后,生成的rasterized_layer中出现了代码预期外的标签值(比如原始数据中存在未处理的类别)
可视化函数的行为差异
高校平台的vis.plot_labels函数可能默认启用了某些扩展渲染选项(比如显示标签的边界、额外的统计bin),而Colab版本中这些选项是关闭的,导致需要的颜色bin数从4变成了5。
解决方案建议
先确认实际的标签数量
在报错的环境中添加以下代码,检查实际的类别数和标签值:import numpy as np print(f"类别名称数量: {len(m_class_names)}") print(f"栅格中的唯一标签值: {np.unique(rasterized_layer)}")如果输出显示实际有5个类别,那你需要将
colors列表扩展为包含5个颜色值(比如添加'gray')。统一依赖库版本
对比Colab和高校平台中相关库的版本,比如运行pip list查看rasterio、matplotlib以及自定义vis模块的版本,将高校平台的版本调整到和Colab一致。动态生成颜色列表
不要硬编码颜色,而是根据实际类别数量动态生成,避免数量不匹配的问题:# 使用matplotlib的内置配色方案自动生成对应数量的颜色 import matplotlib.cm as cm num_classes = len(m_class_names) colors = [cm.get_cmap('tab10')(i) for i in range(num_classes)] # 或者手动扩展颜色列表,确保数量足够 base_colors = ['white', 'green', 'yellow', 'blue'] colors = base_colors + ['gray'] * max(0, num_classes - len(base_colors))检查可视化函数参数
查看vis.plot_labels的文档或源码,看看是否有控制"extensions"的参数(比如add_extensions=False),在调用时关闭该选项,确保只渲染你定义的4个类别。
内容的提问来源于stack exchange,提问作者Akhil Chibber

