解决PIL.putpalette()函数改变255值,将255变成了classID的最后一个值。

文章探讨了在处理图像标签映射时遇到的问题,涉及将标签ID转换为对应的颜色值。作者发现当使用16个类别的颜色映射时,保存PNG图像后会自动将255替换为某种颜色。通过增加颜色映射列表的长度,包括一个黑色值来为255分配颜色,解决了这个问题。在Cityscape的19类别情况中,无需为255分配颜色,只需与类别数量一致的颜色映射长度即可正常工作。

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

【问题】

color_map = [   128, 64,128,
                244, 35,232,
                 70, 70, 70,
                153,153,153,
                250,170, 30,
                107,142, 35,
                 70,130,180,
                220,20,  60,
                255,  0,  0,
                  0,  0,142,
                  0,  0, 70,
                  0, 60,100,
                  0,  0, 90,
                  0,  0,110,
                  0,  0,230,
                119, 11, 32] # cityscape中取了部分颜色值。16个颜色

print('color map len:',len(color_map))
# 打印label_mapping的values值集合。
print(np.unique(list(label_mapping.values())), len(set(list(label_mapping.values()))))
mask = convert_label(mask_data) # 替换部分id为训练集使用id
print('origin:          ',np.unique(mask))
mask_mat = Image.fromarray(mask)
mask_mat.putpalette(color_map)
print('after putpattle: ',np.unique(np.array(mask_mat)))
# save_name 保存成为png图片
mask_mat.save(save_name)
print('read save result:',np.unique(np.array(Image.open(save_name))))

如图所示:16个类,,算上255是17个数值,颜色值的长度应该是16*3=48(这个长度在下方cityscape中是正确的)

此时putpalette函数赋值再保存,后将255更改为classid的最后一位。(尽管putpalette后值没变,但是保存时自动替换了。)

【尝试解决,但不知道是否真的解决】

color_map = [   128, 64,128,
                244, 35,232,
                 70, 70, 70,
                153,153,153,
                250,170, 30,
                107,142, 35,
                 70,130,180,
                220,20,  60,
                255,  0,  0,
                  0,  0,142,
                  0,  0, 70,
                  0, 60,100,
                  0,  0, 90,
                  0,  0,110,
                  0,  0,230,
                119, 11, 32,# cityscape中取了部分颜色值
                 0, 0, 0]  # 多加了一行,难道是给255一个黑色????

print('color map len:',len(color_map))
# 打印label_mapping的values值集合。
print(np.unique(list(label_mapping.values())), len(set(list(label_mapping.values()))))
mask = convert_label(mask_data) # 替换部分id为训练集使用id
print('origin:          ',np.unique(mask))
mask_mat = Image.fromarray(mask)
mask_mat.putpalette(color_map)
print('after putpattle: ',np.unique(np.array(mask_mat)))
# save_name 保存成为png图片
mask_mat.save(save_name)
print('read save result:',np.unique(np.array(Image.open(save_name))))
  1. 还是16个类,但是将颜色值的长度改为(16+1)*3=51, 貌似得到解决。保存方式不变,和上方问题的修改之处只在于colormap的长度+1.

  1. 将mask_mat.putpalette(color_map)改行注释掉

# mask_mat.putpalette(color_map)

也可以得到下面的结果

【cityscape】

color_map = [128, 64,128,
             244, 35,232,
              70, 70, 70,
             102,102,156,
             190,153,153,
             153,153,153,
             250,170, 30,
             220,220,  0,
             107,142, 35,
             152,251,152,
              70,130,180,
             220, 20, 60,
             255,  0,  0,
               0,  0,142,
               0,  0, 70,
               0, 60,100,
               0, 80,100,
               0,  0,230,
             119, 11, 32]# cityscape 19类颜色。

print('color map len:',len(color_map))
# 打印label_mapping的values值集合。
print(np.unique(list(label_mapping.values())), len(set(list(label_mapping.values()))))
mask = convert_label(mask_data) # 替换部分id为训练集使用id
print('origin:          ',np.unique(mask))
mask_mat = Image.fromarray(mask)
mask_mat.putpalette(color_map)
print('after putpattle: ',np.unique(np.array(mask_mat)))
# save_name 保存成为png图片
mask_mat.save(save_name)
print('read save result:',np.unique(np.array(Image.open(save_name))))

当尝试用cityscape转换class为19类的代码进行转换时:

发现颜色值为19*3=57 即可正常运行,尽管算上255一共是20个类【这与我设定的颜色值和长度是一致的,不会给255颜色。只需要19个颜色即可。】。

一模一样的代码。只是更改了label替换的值和color map对应的长度,为什么就会出现上面的问题呢?

### 使用PIL读取图片像素 为了使用 `PIL.Image` 对象获取图片的像素,通常会先加载图像文件创建一个 `PIL.Image` 实例。对于彩色图像是由红、绿、蓝三原色组成,在某些情况下还可能有透明度通道(Alpha)。当通过 `Image.open()` 方法打开一张PNG格式或者其他支持透明背景的图片时,如果该图片确实含有alpha通道,则返回的对象将会表示这一点。 一旦有了 `PIL.Image` 的实例之后,就可以调用 `.getpixel(xy)` 函数来访问特定坐标的像素颜色信息[^1]。不过更常见的方式是将整个图像转换成NumPy数组以便于后续处理: ```python from PIL import Image import numpy as np image_path = "example.png" img = Image.open(image_path) # 将图像数据转化为numpy数组形式 img_array = np.array(img) print(f"Array shape: {img_array.shape}") # 输出形状如 (height, width, channels) ``` 上述代码片段展示了如何把来自路径 `"example.png"` 的图像导入为 NumPy 数组,并打印其尺寸大小。这里 `(height, width, channels)` 表明了高度、宽度以及色彩通道的数量——对于 RGB 图像来说通常是三个通道;而对于 RGBA 图像则会有四个通道,最后一个代表不透明度[^4]。 另外需要注意的是,虽然可以直接使用 `PIL.Image.getdata()` 来获得一维列表形式的所有像素点的信息,但对于大多数应用而言,将其转变为二维甚至三维结构化的 NumPy 数组更加方便实用[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值