当前位置:网站首页>labelme标注不同物体显示不同颜色以及批量转换
labelme标注不同物体显示不同颜色以及批量转换
2022-07-25 06:27:00 【期待686】
最近在使用labelme标注数据时遇到一些问题:
如上图中,蓝色分别为crack,person,dog三类。正常应该是3种不同颜色
解决方案:
1.labelme版本

2、下载labelme后进行文件修改
由于博主想要的是rgb三通道的彩色图,所以标注出的是三通道的rgb值。
因此本教程适合想要标注的物体是彩色图案的读者,不是灰度图。
2.1 label.py文件的修改
#博主的参考路径为:
C:\ProgramData\Anaconda3\envs\labelme\Lib\site-packages\imgviz
修改内容如下:
import numpy as np
from . import color as color_module
from . import draw as draw_module
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
#我认为添加的一段,自己设置不同类别的rgb值
cmap[0,:] = [255,255,255] #背景的rgb值
cmap[1,:] = [255,0,0] #车的rgb
cmap[2,:] = [0,255,0] #人的rgb
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
def label2rgb(
label,
img=None,
alpha=0.5,
label_names=None,
font_size=30,
thresh_suppress=0,
colormap=None,
loc="centroid",
):
"""Convert label to rgb. Parameters ---------- label: numpy.ndarray, (H, W), int Label image. img: numpy.ndarray, (H, W, 3), numpy.uint8 RGB image. alpha: float Alpha of RGB (default: 0.5). label_names: list of string Label id to label name. font_size: int Font size (default: 30). thresh_suppress: float Threshold of label ratio in the label image. colormap: numpy.ndarray, (M, 3), numpy.uint8 Label id to color. By default, :func:`~imgviz.label_colormap` is used. loc: string Location of legend (default: 'centroid'). 'lt' and 'rb' are supported. Returns ------- res: numpy.ndarray, (H, W, 3), numpy.uint8 Visualized image. """
if colormap is None:
colormap = label_colormap()
res = colormap[label]
random_state = np.random.RandomState(seed=1234)
mask_unlabeled = label < 0
res[mask_unlabeled] = random_state.rand(*(mask_unlabeled.sum(), 3)) * 255
if img is not None:
if img.ndim == 2:
img = color_module.gray2rgb(img)
res = (1 - alpha) * img.astype(float) + alpha * res.astype(float)
res = np.clip(res.round(), 0, 255).astype(np.uint8)
if label_names is None:
return res
if loc == "centroid":
for label_i in np.unique(label):
if label_i == -1:
continue # unlabeled
mask = label == label_i
if 1.0 * mask.sum() / mask.size < thresh_suppress:
continue
y, x = np.array(_center_of_mass(mask), dtype=int)
if label[y, x] != label_i:
Y, X = np.where(mask)
point_index = np.random.randint(0, len(Y))
y, x = Y[point_index], X[point_index]
text = label_names[label_i]
height, width = draw_module.text_size(text, size=font_size)
color = color_module.get_fg_color(res[y, x])
res = draw_module.text(
res,
yx=(y - height // 2, x - width // 2),
text=text,
color=color,
size=font_size,
)
elif loc in ["rb", "lt"]:
unique_labels = np.unique(label)
unique_labels = unique_labels[unique_labels != -1]
text_sizes = np.array(
[
draw_module.text_size(label_names[l], font_size)
for l in unique_labels
]
)
text_height, text_width = text_sizes.max(axis=0)
legend_height = text_height * len(unique_labels) + 5
legend_width = text_width + 40
height, width = label.shape[:2]
legend = np.zeros((height, width, 3), dtype=np.uint8)
if loc == "rb":
aabb2 = np.array([height - 5, width - 5], dtype=float)
aabb1 = aabb2 - (legend_height, legend_width)
elif loc == "lt":
aabb1 = np.array([5, 5], dtype=float)
aabb2 = aabb1 + (legend_height, legend_width)
else:
raise ValueError("unexpected loc: {}".format(loc))
legend = draw_module.rectangle(
legend, aabb1, aabb2, fill=(255, 255, 255)
)
alpha = 0.5
y1, x1 = aabb1.round().astype(int)
y2, x2 = aabb2.round().astype(int)
res[y1:y2, x1:x2] = (
alpha * res[y1:y2, x1:x2] + alpha * legend[y1:y2, x1:x2]
)
for i, l in enumerate(unique_labels):
box_aabb1 = aabb1 + (i * text_height + 5, 5)
box_aabb2 = box_aabb1 + (text_height - 10, 20)
res = draw_module.rectangle(
res, aabb1=box_aabb1, aabb2=box_aabb2, fill=colormap[l]
)
res = draw_module.text(
res,
yx=aabb1 + (i * text_height, 30),
text=label_names[l],
size=font_size,
)
else:
raise ValueError("unsupported loc: {}".format(loc))
return res
def _center_of_mass(mask):
assert mask.ndim == 2 and mask.dtype == bool
mask = 1.0 * mask / mask.sum()
dx = np.sum(mask, 0)
dy = np.sum(mask, 1)
cx = np.sum(dx * np.arange(mask.shape[1]))
cy = np.sum(dy * np.arange(mask.shape[0]))
return cy, cx
需要修改的地方博主已经做了注释和说明。
2.2 json_to_dataset.py文件的修改
#博主的参考路径:
C:\ProgramData\Anaconda3\envs\labelme\Lib\site-packages\labelme\cli
实现json数据的批量转换,输出到指定目录。
修改如下内容:
import argparse
import base64
import json
import os
import os.path as osp
import imgviz
import PIL.Image
from labelme.logger import logger
from labelme import utils
def main():
logger.warning(
"批量处理json文件。"
"注意!文件夹中不能有其他文件存在。"
)
parser = argparse.ArgumentParser()
parser.add_argument('json_file')
parser.add_argument('-o', '--out', default=None)
args = parser.parse_args()
json_file = args.json_file
# 输出路径
if args.out is None:
out_dir = osp.basename(json_file).replace('.', '_')
out_dir = osp.join(osp.dirname(json_file), out_dir)
else:
out_dir = args.out
if not osp.exists(out_dir):
os.makedirs(out_dir)
# 处理多个文件
json_files_names = os.listdir(json_file)
for i in range(0, len(json_files_names)):
path = os.path.join(json_file, json_files_names[i])
logger.info("正在处理: {}".format(path))
if os.path.isfile(path):
try:
data = json.load(open(path, encoding='UTF-8'))
except:
data = json.load(open(path))
if data['imageData']:
imageData = data['imageData']
else:
imagePath = os.path.join(os.path.dirname(path), data['imagePath'])
try:
with open(imagePath, 'rb', encoding='UTF-8') as f:
imageData = f.read(encoding='UTF-8')
imageData = base64.b64encode(imageData).decode('utf-8')
except:
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,'car':1,'person':2} #在这一行更改,改成自己的类别数
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(
label=lbl, img=imgviz.asgray(img), label_names=label_names, loc="rb"
)
# 新建路径
save_dir = osp.join(out_dir, json_files_names[i].split('.')[0])
if not os.path.exists(save_dir):
os.makedirs(save_dir)
PIL.Image.fromarray(img).save(osp.join(save_dir, 'img.png'))
utils.lblsave(osp.join(save_dir, 'label.png'), lbl)
PIL.Image.fromarray(lbl_viz).save(osp.join(save_dir, 'label_viz.png'))
with open(osp.join(save_dir, 'label_names.txt'), 'w') as f:
for lbl_name in label_names:
f.write(lbl_name + '\n')
logger.info("Saved to: {}".format(save_dir))
3、运行转换程序
1、激活安装的labelme环境。
查看环境
conda info --envs
激活环境
activate labelme
2.进入 labelme_json_to_dataset.exe 文件所在路径,也就是第2步你复制的路径,进入命令如下
cd D:\Anaconda3\envs\labelme\Scripts
3.输入 labelme_json_to_dataset.exe+空格+【你待转化的 json 文件所在路径】
labelme_json_to_dataset.exe 【你待转化的 json 文件所在路径】
4、 查看转化结果


上述两个图中黄色的标注为dog,同一颜色表示
Tips:
针对以上代码,因为labelme的版本问题,可能会存在的一些小问题,如:
imgviz 版本问题,1.5.0有问题,1.2.0测试没问题
会报错:TypeError: label2rgb() got an unexpected keyword argument ‘img’
解决办法:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple imgviz==1.2.0
边栏推荐
- Some common interview questions about IO stream and string
- 2022 "strong country Cup" preliminary WP (with script and detailed process)
- JS how to delete an element without deleting its child elements
- What projects can make money online? Is it reliable to be we media?
- Application of first-order complementary filtering to STM32 ADC acquisition
- 4、 MFC toolbar, runtime class information mechanism, runtime creation mechanism
- 二叉搜索树(DAY 75)
- 【剑指Offer】模拟实现atoi
- 【C语言】指针和数组的深入理解(第一期)
- Cout format output common functions and flags summary
猜你喜欢

ROI pooling and ROI align

Detailed explanation of the difference, working principle and basic structure between NMOS and PMOS

What determines the "personality" of AI robots?
![[datawhale202207] reinforcement learning: the foundation of reinforcement learning](/img/1e/6ba657da14508854207aac51992ad8.png)
[datawhale202207] reinforcement learning: the foundation of reinforcement learning

Bubble sort code implementation
![[C language] in depth understanding of pointers and arrays (phase I)](/img/4b/26cf10baa29eeff08101dcbbb673a2.png)
[C language] in depth understanding of pointers and arrays (phase I)

Keil uvisin5 code auto completion or code Association

C#控件开源库:MetroFramework的下载
![[reprint] pycharm packages.Py program as executable exe](/img/9c/02a967fb08ca54bb742cf69c4578a7.png)
[reprint] pycharm packages.Py program as executable exe

Daily question brushing record (XXVIII)
随机推荐
Prometheus operator configures promethesrule alarm rules
函数模板学习记录
Evolution of coupon architecture under C2B mode
Solve the problem of invalid modification of QT 5 interface. Solve the problem of invalid modification of qtdesigner
HTX00001_ Keil51 bug encountered in serial port parsing
"Wei Lai Cup" 2022 Niuke summer multi school training camp 2 link with game glitch (SPFA finds positive and negative links)
Bubble sort code implementation
[Luogu p6629] string (runs) (tree array)
Unity animator animation and state machine
The LAF protocol elephant of defi 2.0 may be one of the few profit-making means in your bear market
Using JS to realize the linkage effect of form form's secondary menu
U-boot-1.1.6 transplant notes (beginner)
DOM event type
JS gets the text selected by the mouse and is in the selected state
Easy to use code statistics tool
VBS common built-in functions (2)
长安链双花交易防范策略
Special episode of Goddess Festival | exclusive interview with Chinese AI goddess Zhang Qingqing's transformation from a female learning tyrant to a female entrepreneur
JTAG debugging source level debugging of arm bare board debugging
Detailed explanation of arm instruction CMP