Mask-RCNN应用 - 数据增强基础准备 - labelme 标注24位深RGB标注图转换为8位深RGB标注图

MaskRCNN入门路径–> Mask-RCNN应用研究方法 - 持续更新中

如有问题或需要源码、指导,请私聊留下联系方式或用手机打开https://m.tb.cn/h.fINaraE?tk=PCzA2jPp4V0进行咨询

本文介绍如何将24位深图片根据调色表转换位8位深图片
能够提供为何training时出现"IndexError: boolean index did not match indexed array along dimension 0; dimension is 12 but corresponding boolean dimension is 192"错误
Complete:2020/08/27 - 文章内容完成

文章目录

      • 前言
        • 1、关于Mask-RCNN使用的标注结果文件
        • 2、关于labelme标注生成的label.png
      • json_to_dataset.py源代码分析
        • 1、json_to_dataset.py中的8位调色码生成
        • 2、json_to_dataset.py中将label转换为RGB图片
      • 24位深图转换为8位深图的整体过程
      • 完整代码

前言

1、关于Mask-RCNN使用的标注结果文件

  • Mask-RCNN学习 - 批量生成训练所需文件并训练自己的数据集(技巧与防坑)文章中已经介绍过labelme生成的标定文件。但是实际上Mask-RCNN使用的文件仅为info.yaml和label.png文件,其中info.yaml文件存储的是label-names,label.png文件则为8位深RGB图,存储了label-names对应的label-indexes。
  • 因此label.png非常重要,无论之后通过何种方式处理,仍然需要保证其为8位深RGB图,并且调色板也需与labelme中的保持一致。
  • 如果使用错误在training时会出现类似"IndexError: boolean index did not match indexed array along dimension 0; dimension is 12 but corresponding boolean dimension is 192"的错误
    Mask-RCNN应用 - 数据增强基础准备 - labelme 标注24位深RGB标注图转换为8位深RGB标注图_第1张图片

2、关于labelme标注生成的label.png

  • 新编的labelme软件生成的label.png已经转换为了8位深RGB图,因此无需考虑24位转8位的问题。
  • 然而老版的labelme或者通过其余方式处理过后保存的label.png依然有可能是24位深图片
    例如:
import cv2
img = cv2.imread("label.png")  #默认以24位读取方式读入,shape=[rows,cols,channel]
cv2.imwrite("label.png",img)   #此时保存下来的label.png已经转为24位图

因此希望找到一个方法能够将这种24位深的图转换为8位深图,为将来的数据处理做准备。

json_to_dataset.py源代码分析

json_to_dataset.py中存储了如何将json中的label-mask以及label-index信息转换成label.png的过程,因此本文中的代码借用了json_to_dataset.py的部分代码

1、json_to_dataset.py中的8位调色码生成

  • label_colormap(n_label=256, value=None)生成了256个RGB调色码,colormap.shape = [256,3]
def label_colormap(n_label=256, value=None):
    """Label colormap.

    Parameters
    ----------
    n_labels: int
        Number of labels (default: 256).
    value: float or int
        Value scale or value of label color in HSV space.

    Returns
    -------
    cmap: numpy.ndarray, (N, 3), numpy.uint8
        Label id to colormap.

    """

    def bitget(byteval, idx):
        return (byteval & (1 << idx)) != 0

    cmap = np.zeros((n_label, 3), dtype=np.uint8)
    for i in range(0, n_label):
        id = i
        r, g, b = 0, 0, 0
        for j in range(0, 8):
            r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
            g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
            b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
            id = id >> 3
        cmap[i, 0] = r
        cmap[i, 1] = g
        cmap[i, 2] = b

    if value is not None:
        hsv = rgb2hsv(cmap.reshape(1, -1, 3))
        if isinstance(value, float):
            hsv[:, 1:, 2] = hsv[:, 1:, 2].astype(float) * value
        else:
            assert isinstance(value, int)
            hsv[:, 1:, 2] = value
        cmap = hsv2rgb(hsv).reshape(-1, 3)
    return cmap

2、json_to_dataset.py中将label转换为RGB图片

  • label.shape=[rows, cols],label[r,c] = label_index
  • json_to_dataset.py中将label对应到colormap中对应index中的值,即能将label映射到图片中的像素,label_rgb[r,c] = colormap[label[r,c]]
 def lblsave(filename, lbl):
    if osp.splitext(filename)[1] != '.png':
        filename += '.png'
    # Assume label ranses [-1, 254] for int32,
    # and [0, 255] for uint8 as VOC.
    if lbl.min() >= -1 and lbl.max() < 255:
        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode='P')
        colormap = label_colormap()
        lbl_pil.putpalette(colormap.flatten())
        lbl_pil.save(filename)
    else:
        raise ValueError(
            '[%s] Cannot save the pixel-wise class label as PNG. '
            'Please consider using the .npy format.' % filename
        )

24位深图转换为8位深图的整体过程

#======================================================================
#
#        Copyright (C) 2020
#        All rights reserved
#
#        description :
#
#        created by 天木青(https://blog.csdn.net/qq_15615505) at  08/27/2020 18:41:28
#
#======================================================================

# 读取调色板
colormap = label_colormap()

# 读入图片并将opencv的BGR转换为RGB格式
img = cv2.imread("label-24.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 将24位深图片中的[r,g,b]对应到colormap反求出label
lbls = np.zeros(shape=[img.shape[0], img.shape[1]], dtype=np.int32)
len_colormap = len(colormap)
indexes = np.nonzero(img)

for i, j in zip(indexes[0], indexes[1]):
    for k in range(len_colormap):
        if all(img[i, j, :3] == colormap[k]):
            lbls[i, j] = k
            break
            
#####
##### 此处添加对lal图的变换处理过程,注意数据类型为int32
#####

# 将label再转换成8位label.png
lblsave(os.path.join(os.getcwd(), 'label.png'), lbls)

完整代码

如需完整代码,请私信博主留言!
近期好多同学私信我需要源码,在此声明一下:本文中的代码labelme部分源代码未放在代码中,需要各位自己补充,其余的功能已经完整。如果还有什么问题,请私信或用手机打开https://m.tb.cn/h.fINaraE?tk=PCzA2jPp4V0进行咨询,谢谢!

你可能感兴趣的:(计算机视觉-深度学习,#,Mask-RCNN,python,深度学习,tensorflow)