0.应用背景
语义分割 标签文件,一般为灰度,转换为彩色方便查看预训练模型在不同模型上推理结果。GANs 的很多模型,数据集需要彩色 的语义便签、或灰度 的语义便签训练,二者之间的转换是比较重要的。(例如 pix2pix |pix2pixhd)
1. label2color
- 读取
.png 格式的语义分割图(.jpg会改变像素值) - 设置numpy格式的
灰度与rgb彩色映射表 (colormap) - numpy快速转换
1.1 随机映射颜色
简略代码:完整见附录
src_label = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
n_label = 20
random_state = np.random.RandomState(seed=1234)
color_custom_map = np.random.randint(low=0, high=255, size=(n_label, 3), dtype=np.uint8)
color_img = colormap[src_label]
save_path=os.path.join('./out_color', name)
cv2.imwrite(save_path, color_img)
随机映射颜色效果(每次启动都不同)
1.2 语义分割常用映射
cmap = np.zeros((n_label, 3), dtype=np.uint8)
for i in range(n_label):
id = i
r, g, b = 0, 0, 0
for j in range(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
if not rgb1_bgr0:
cmap[i, 0] = b
cmap[i, 1] = g
cmap[i, 2] = r
else:
cmap[i, 0] = r
cmap[i, 1] = g
cmap[i, 2] = b
2. 彩色label转换为gray
简略代码:完整见附录
def color2gray(image_rgb, rgb_mapping):
gray_img = np.zeros(shape=(image_rgb.shape[0], image_rgb.shape[1]), dtype=np.uint8)
_st_rgb2gray = time.time()
for map_idx, rgb in enumerate(rgb_mapping):
idx = np.where((image_rgb[..., 0] == rgb[0]) & (image_rgb[..., 1] == rgb[1]) & (image_rgb[..., 2] == rgb[2]))
gray_img[idx] = map_idx
print("rgb 2 gray time used: {}".format(time.time() - _st_rgb2gray))
return gray_img
3. 运行附录程序
- label 转化到 彩色 再转换为 label 根据结果灰度值没发生跳变(语义类别不变),证明
转换成功可逆
3.1 逐像素查看灰度验证(非必要 )
4. 附录
4.1 main.py
import os
import cv2
import numpy as np
import rgb2gray2rgb
import label2color
def label_color_label(img_path, color_map, debug=1):
src_label = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
'''
label2color
'''
color_img = rgb2gray2rgb.gray2color(src_label, color_map)
dir, name = os.path.split(img_path)
save_path=os.path.join('./out_color', name)
cv2.imwrite(save_path, color_img)
'''
color2label
'''
gray_img = rgb2gray2rgb.color2gray(color_img, color_map)
'''
原始lable图像的灰度值
lable2color2label图像的灰度值,
'''
pix_value = np.unique(src_label)
print('src_label_value', pix_value)
pix_value = np.unique(gray_img)
print("label2color2label_value", pix_value)
if debug:
cv2.imshow('label2color', color_img)
cv2.imshow('color2label', gray_img)
cv2.waitKey(0)
if __name__ == '__main__':
img_dir = './label/'
n_label = 20
color_map1 = label2color.label_colormap(n_label=n_label, rgb1_bgr0=0)
'''
random gene color map
'''
random_state = np.random.RandomState(seed=1234)
color_custom_map = np.random.randint(low=0, high=255, size=(n_label, 3), dtype=np.uint8)
for img in sorted(os.listdir(img_dir)):
if not img.endswith((".png", ".jpg")):
continue
img_path = os.path.join(img_dir, img)
label_color_label(img_path, color_map1, debug=1)
4.2 rgb2gray2rgb.py
import time
import numpy as np
import cv2
def gray2color(gray_img, colormap):
'''
:param gray_img: (h,w) max_value=num_class
:param colormap: (num_class,3) # colormap的索引对应了灰度值
:return: color_img: (h,w,3) colormap的索引与label中灰度值一一顺序对应;如colormap[0]的颜色对应gray_image==0
'''
color_img = colormap[gray_img]
return color_img
def color2gray(image_rgb, rgb_mapping):
gray_img = np.zeros(shape=(image_rgb.shape[0], image_rgb.shape[1]), dtype=np.uint8)
_st_rgb2gray = time.time()
for map_idx, rgb in enumerate(rgb_mapping):
idx = np.where((image_rgb[..., 0] == rgb[0]) & (image_rgb[..., 1] == rgb[1]) & (image_rgb[..., 2] == rgb[2]))
gray_img[idx] = map_idx
print("rgb 2 gray time used: {}".format(time.time() - _st_rgb2gray))
return gray_img
4.3 label2color.py
'''
https://github.com/hhj1897/face_parsing/blob/master/ibug/face_parsing/utils.py
'''
import numpy as np
random_state = np.random.RandomState(seed=1234)
def label_colormap(n_label=11,rgb1_bgr0=1):
"""Label colormap.
Parameters
----------
n_labels: int
Number of labels (default: 11).
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.
"""
if n_label == 11:
cmap = np.array(
[
(0, 0, 0),
(255, 255, 0),
(139, 76, 57),
(139, 54, 38),
(0, 205, 0),
(0, 138, 0),
(154, 50, 205),
(72, 118, 255),
(255, 165, 0),
(0, 0, 139),
(255, 0, 0),
],
dtype=np.uint8,
)
elif n_label == 19:
cmap = np.array(
[
(0, 0, 0),
(204, 0, 0),
(76, 153, 0),
(204, 204, 0),
(51, 51, 255),
(204, 0, 204),
(0, 255, 255),
(255, 204, 204),
(102, 51, 0),
(255, 0, 0),
(102, 204, 0),
(255, 255, 0),
(0, 0, 153),
(0, 0, 204),
(255, 51, 153),
(0, 204, 204),
(0, 51, 0),
(255, 153, 51),
(0, 204, 0),
],
dtype=np.uint8,
)
else:
def bitget(byteval, idx):
return (byteval & (1 << idx)) != 0
cmap = np.zeros((n_label, 3), dtype=np.uint8)
gray_map=np.zeros((n_label))
for i in range(n_label):
id = i
r, g, b = 0, 0, 0
for j in range(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
if not rgb1_bgr0:
cmap[i, 0] = b
cmap[i, 1] = g
cmap[i, 2] = r
else:
cmap[i, 0] = r
cmap[i, 1] = g
cmap[i, 2] = b
return cmap
4.4 灰度原图
|