voc分割数据集 pil调色板

voc分割数据集有两种,文件夹名字分别是SegmentationClass,SegmentationClassAug,其中SegmentationClass文件夹图片样式如下:
voc分割数据集 pil调色板_第1张图片
SegmentationClassAug文件夹图片样式如下:
voc分割数据集 pil调色板_第2张图片
今天来说下SegmentationClass文件夹带彩色图的,读一个deeplab的pytorch代码的时候,我就在找是怎么把颜色对应到标签图的,找了半天没有,但是发现最后的处理得到的标签图确实是0-21的像素,可是哪里处理了的了.

def _make_img_gt_point_pair(self, index):
        _img = Image.open(self.images[index]).convert('RGB')
        _target = Image.open(self.categories[index])

        return _img, _target

只有一处是通过PIL读取图片,然后我惊奇的发现仅仅是通过这个读就已经转成了0-21的标签图!!!???why?

def _make_img_gt_point_pair(self, index):
        _img = Image.open(self.images[index]).convert('RGB')
        _target = Image.open(self.categories[index])

        _img.show()
        _target.show()

        import numpy
        img = numpy.array(_img)
        targe = numpy.array(_target)

用pilshow出来,还是彩色图
voc分割数据集 pil调色板_第3张图片
但是我用numpy看targe已经是单通道了...然后我再用opencv显示,

def _make_img_gt_point_pair(self, index):
        _img = Image.open(self.images[index]).convert('RGB')
        _target = Image.open(self.categories[index])

        _img.show()
        _target.show()


        import numpy
        img = numpy.array(_img)
        targe = numpy.array(_target)

        import cv2
        cv2.imshow("opencv-show-pil",targe)
        cv2.waitKey()

        mm = cv2.imread(self.categories[index],-1)
        cv2.imshow("opencv-read", mm)
        cv2.waitKey()

voc分割数据集 pil调色板_第4张图片
这里可以看到,直接读取路径确实是彩色图,但是经过pil打开之后,就变成了标签图!神奇吧!

def _make_img_gt_point_pair(self, index):
        _img = Image.open(self.images[index]).convert('RGB')
        _target = Image.open(self.categories[index])

        import numpy
        img = numpy.array(_img)
        targe = numpy.array(_target)

        import cv2
        cv2.imshow("opencv-show-pil",targe)
        cv2.waitKey()

        mm = cv2.imread(self.categories[index],-1)
        cv2.imshow("opencv-read", mm)
        cv2.waitKey()

        _img.show()
        _target.show()

        print(_img.format, _img.size, _img.mode)
        print(_target.format, _target.size, _target.mode)

打印pil的一些属性,

None (438, 500) RGB
PNG (438, 500) P

可以发现标签图的mode是p. 百度了一下

modes 	描述
1 	1位像素,黑和白,存成8位的像素
L 	8位像素,黑白
P 	8位像素,使用调色板映射到任何其他模式
RGB 	3× 8位像素,真彩
RGBA 	4×8位像素,真彩+透明通道
CMYK 	4×8位像素,颜色隔离
YCbCr 	3×8位像素,彩色视频格式
I 	32位整型像素
F 	32位浮点型像素

P 8位像素,使用调色板映射到任何其他模式
啥意思,没看懂. 然后有段解释:
https://www.zhihu.com/question/263994588
在PIL中,图像有很多种模式,如'L'模式,'P'模式,还有常见的'RGB'模式。模式'P'为8位彩色图像,它的每个像素用8个bit表示,其对应的彩色值是按照调色板索引值查询出来的。
pascal voc的标签图像的模式正是'P'模式。
但是它怎么知道我哪个颜色对应哪个类别的呢.
应该是pil这个调色板是内置的,

print(_target.getpalette())

palette = np.array(_target.getpalette(), dtype=np.uint8).reshape((256, 3))
print(palette)

print(_target.getpalette())打印出很长的一串
[0, 0, 0, 128, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 128, 128, 0, 128, 0, 128, 128, 128, 128, 128, 64, 0, 0, 192, 0, 0, 64, 128, 0, 192, 128, 0, 64, 0, 128, 192, 0, 128, 64, 128, 128, 192, 128, 128, 0, 64, 0, 128, 64, 0, 0, 192, 0, 128, 192, 0, 0,......]
转为numpy,
palette = np.array(_target.getpalette(), dtype=np.uint8).reshape((256, 3))
print(palette)
打印如下:
[[ 0 0 0]
[128 0 0]
[ 0 128 0]
[128 128 0]
[ 0 0 128]
[128 0 128]
[ 0 128 128]
[128 128 128]
[ 64 0 0]
[192 0 0]
[ 64 128 0]
[192 128 0]
[ 64 0 128]
[192 0 128]
[ 64 128 128]
[192 128 128]
[ 0 64 0]
[128 64 0]
[ 0 192 0]
[128 192 0]
[ 0 64 128]
[128 64 128]
[ 0 192 128]
[128 192 128]
[ 64 64 0]
[192 64 0]
[ 64 192 0]
[192 192 0]
[ 64 64 128]
...

原来如此!

你可能感兴趣的:(voc分割数据集 pil调色板)