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使用的标注结果文件
-
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"的错误
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进行咨询,谢谢!