1、labelme标注
图片和json文件保存在同一文件夹下。
2、将灰度值映射到特定的类别,指定颜色
1. 修改label.py文件.
我的路径:E:/WorkSoftware/Install/Anaconda3/envs/labelme/Lib/site-packages/imgviz/
# 在这里修改颜色,修改要对应json_to_dataset.py里面自己的类别,
# 颜色可以自己选择,以下是示例
cmap[1, :] = [0, 255, 0] # class 1
cmap[2, :] = [255, 0, 0] # class 2
以下是完整代码:
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):
shape = byteval.shape + (8,)
return np.unpackbits(byteval).reshape(shape)[..., -1 - idx]
i = np.arange(n_label, dtype=np.uint8)
r = np.full_like(i, 0)
g = np.full_like(i, 0)
b = np.full_like(i, 0)
i = np.repeat(i[:, None], 8, axis=1)
i = np.right_shift(i, np.arange(0, 24, 3)).astype(np.uint8)
j = np.arange(8)[::-1]
r = np.bitwise_or.reduce(np.left_shift(bitget(i, 0), j), axis=1)
g = np.bitwise_or.reduce(np.left_shift(bitget(i, 1), j), axis=1)
b = np.bitwise_or.reduce(np.left_shift(bitget(i, 2), j), axis=1)
cmap = np.stack((r, g, b), axis=1).astype(np.uint8)
# 在这里修改颜色,修改要对应json_to_dataset.py里面自己的类别
cmap[1, :] = [0, 255, 0] # lane
if value is not None:
hsv = color_module.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 = color_module.hsv2rgb(hsv).reshape(-1, 3)
return cmap
2. 修改json_to_dataset.py 文件。
我的路径:E:/WorkSoftware/Install/Anaconda3/envs/labelme/Lib/site-packages/labelme/cli/
label_name_to_value = {"_background_": 0}
# 修改为自己的类别,我只有一个类别,所以添加了一个
label_name_to_value = {"_background_": 0, "lane": 1}
3、生成img.png、label.png、label_names.txt、label_viz.png
由于labelme里面的json_to_dataset.py只能转换单张json文件,不能处理文件夹,因此我在自己的项目目录下做了修改,新建文件命名为json_to_dataset_labelme.py。完整代码如下:
# json_to_dataset_labelme.py
import argparse
import base64
import json
import os
import os.path as osp
import imgviz
import PIL.Image
from labelme import utils
from labelme.logger import logger
def convert_json_files(input_folder, output_folder=None):
for root, dirs, files in os.walk(input_folder):
for file in files:
if file.endswith(".json"):
json_file_path = osp.join(root, file)
convert_single_json(json_file_path, output_folder)
def convert_single_json(json_file, output_folder=None):
logger.warning(
"DEPRECATED: This script will be removed in the near future. "
"Please use `labelme_export_json` instead."
)
logger.warning(
"NOTE: This script is aimed to demonstrate how to convert a JSON file "
"to a single image dataset. so it won't handle multiple JSON files to "
"generate a real-use dataset."
)
# 获取 JSON 文件的文件名(不包括扩展名)
json_file_name = osp.splitext(osp.basename(json_file))[0]
if output_folder is None:
out_dir = osp.join(osp.dirname(json_file), json_file_name)
else:
out_dir = osp.join(output_folder, json_file_name)
if not osp.exists(out_dir):
os.mkdir(out_dir)
# if output_folder is None:
# out_dir = osp.basename(json_file).replace(".", "_")
# out_dir = osp.join(osp.dirname(json_file), out_dir)
# else:
# out_dir = output_folder
# if not osp.exists(out_dir):
# os.mkdir(out_dir)
data = json.load(open(json_file))
imageData = data.get("imageData")
if not imageData:
imagePath = os.path.join(os.path.dirname(json_file), data["imagePath"])
with open(imagePath, "rb") as f:
imageData = f.read()
imageData = base64.b64encode(imageData).decode("utf-8")
img = utils.img_b64_to_arr(imageData)
label_name_to_value = {"_background_": 0, "lane": 1}
for shape in sorted(data["shapes"], key=lambda x: x["label"]):
label_name = shape["label"]
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
lbl, _ = utils.shapes_to_label(
img.shape, data["shapes"], label_name_to_value
)
label_names = [None] * (max(label_name_to_value.values()) + 1)
for name, value in label_name_to_value.items():
label_names[value] = name
lbl_viz = imgviz.label2rgb(
lbl, imgviz.asgray(img), label_names=label_names, loc="rb"
)
PIL.Image.fromarray(img).save(osp.join(out_dir, "img.png"))
utils.lblsave(osp.join(out_dir, "label.png"), lbl)
PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, "label_viz.png"))
with open(osp.join(out_dir, "label_names.txt"), "w") as f:
for lbl_name in label_names:
f.write(lbl_name + "\n")
logger.info(f"Saved to: {out_dir}")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("input", help="Input folder containing JSON files or a single JSON file")
parser.add_argument("-o", "--out", default=None, help="Output folder for converted images")
args = parser.parse_args()
input_path = args.input
output_path = args.out
if os.path.isdir(input_path):
convert_json_files(input_path, output_path)
elif os.path.isfile(input_path):
convert_single_json(input_path, output_path)
else:
logger.error("Invalid input path. Please provide a valid file or folder path.")
if __name__ == "__main__":
main()
运行命令行,即可:
python json_to_dataset_labelme.py path/your_filename -o path/your_output_filename
结果如下所示:
4、gtFine标签图像
上面生成的label.png的R通道就是需要的gtFine标签图像。
要确保在提取 R 通道之前标签图(label.png)的 R 通道的像素值应该对应于类别的标签值,而不是原始图像的 R 通道。(步骤2)
# gtFine_labelids.py
import os
import cv2
json_path = './out'
for root, dirs, files in os.walk(json_path):
for file in files:
if file.strip() == "label.png":
file_path = os.path.join(root, file)
src_image_path = os.path.join(root, 'img.png')
image = cv2.imread(file_path)
src = cv2.imread(src_image_path)
folder_name = os.path.split(root)[-1]
file_name = folder_name + '_' + file.split('_')[0] + '.png'
# label处理 直接取R通道的图像就是gtFine
B, G, R = cv2.split(image)
path = os.path.join(os.path.abspath('.'), 'gtFine')
if not os.path.exists(path):
os.makedirs(path)
labelId_image = os.path.join(path, file_name.split('.')[0] + '_gtFine_labelIds.' + file_name.split('.')[-1])
print(labelId_image)
cv2.imwrite(labelId_image, R)
src_image_path = os.path.join(os.path.abspath('.'), 'leftImg8bit')
if not os.path.exists(src_image_path):
os.makedirs(src_image_path)
# 保存原始图像
src_image = os.path.join(src_image_path, file_name)
cv2.imwrite(src_image, src)
# 保存原始图像的 R 通道
# src_image = os.path.join(src_image_path, file_name)
# cv2.imwrite(src_image, R)
print(file_name)
5、训练集验证集分割
# train_val_seg.py
import os
import random
import shutil
total_list = []
train_list = []
val_list = []
test_list = []
image_path = './leftImg8bit'
label_path = './gtFine'
# 清空
for dir in ['train', 'val', 'test']:
image_dir = os.path.join(image_path, dir)
label_dir = os.path.join(label_path, dir)
if os.path.exists(image_dir):
shutil.rmtree(image_dir)
os.makedirs(image_dir)
if os.path.exists(label_dir):
shutil.rmtree(label_dir)
os.makedirs(label_dir)
for root, dirs, files in os.walk(image_path):
for file in files:
if file.endswith('png'):
total_list.append(file)
total_size = len(total_list)
train_size = int(total_size * 0.7)
val_size = int(total_size * 0.2)
train_list = random.sample(total_list, train_size)
remain_list = list(set(total_list) - set(train_list))
val_list = random.sample(remain_list, val_size)
test_list = list(set(remain_list) - set(val_list))
print(len(total_list))
print(len(train_list))
print(len(val_list))
print(len(test_list))
image_path = './leftImg8bit'
label_path = './gtFine'
# 清空
for dir in ['train', 'val', 'test']:
image_dir = os.path.join(image_path, dir)
label_dir = os.path.join(label_path, dir)
if os.path.exists(image_dir):
shutil.rmtree(image_dir)
os.makedirs(image_dir)
if os.path.exists(label_dir):
shutil.rmtree(label_dir)
os.makedirs(label_dir)
for file in total_list:
image_path_0 = os.path.join(image_path, file)
label_file = file.split('.')[0] + '_gtFine_labelIds' + '.png'
label_path_0 = os.path.join(label_path, label_file)
if file in train_list:
image_path_1 = os.path.join(image_path, 'train', file)
shutil.move(image_path_0, image_path_1)
label_path_1 = os.path.join(label_path, 'train', label_file)
shutil.move(label_path_0, label_path_1)
elif file in val_list:
image_path_1 = os.path.join(image_path, 'val', file)
shutil.move(image_path_0, image_path_1)
label_path_1 = os.path.join(label_path, 'val', label_file)
shutil.move(label_path_0, label_path_1)
elif file in test_list:
image_path_1 = os.path.join(image_path, 'test', file)
shutil.move(image_path_0, image_path_1)
label_path_1 = os.path.join(label_path, 'test', label_file)
shutil.move(label_path_0, label_path_1)
参考:
将自己的数据制作成cityscape格式_cityscape 格式label 目录-CSDN博客
labelme 制作语义分割(Semantic Segmentation)数据,不同labels指定不同颜色-CSDN博客