labelme\labelimg标注数据可视化

已标注数据的可视化有两种方式:

1.将图片和标注文件(json\xml)放在同一文件夹中,然后用labelme\labelimg打开此文件夹即可查看;

2.解析标注文件,用opencv进行可视化。

显然,本文要讲的是第二种!!!

一、labelimg标注的xml文件可视化

# 导入工具包
import cv2
import matplotlib.pyplot as plt
import xml.etree.ElementTree as ET

# 载入图像
img_path = '3.jpg'
img_bgr = cv2.imread(img_path)

# 可视化
# plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
# plt.show()

# 载入labelimg格式的xml标注文件
xml_path = '3.xml'

xml_inf = open(xml_path)
tree = ET.parse(xml_inf)
# print(tree)
root = tree.getroot()
# print(root)

# 框可视化配置
bbox_color = (255, 129, 0)           # 框的颜色
bbox_thickness = 2                   # 框的线宽

# 框类别文字
bbox_labelstr = {
    'font_size':1,         # 字体大小
    'font_thickness':2,   # 字体粗细
    'offset_x':0,          # X 方向,文字偏移距离,向右为正
    'offset_y':-10,       # Y 方向,文字偏移距离,向下为正
}
# 画框
for obj in root.iter('object'): # 一个object代表一个标注物体

    # 框的类别
    bbox_label = obj.find('name').text

    # 框的两点坐标
    # 左上角坐标
    bbox_top_left_x = int(obj.find('bndbox').find('xmin').text)
    bbox_top_left_y = int(obj.find('bndbox').find('ymin').text)
    # 右下角坐标
    bbox_bottom_right_x = int(obj.find('bndbox').find('xmax').text)
    bbox_bottom_right_y = int(obj.find('bndbox').find('ymax').text)

    # 画矩形:画框
    img_bgr = cv2.rectangle(img_bgr, (bbox_top_left_x, bbox_top_left_y), (bbox_bottom_right_x, bbox_bottom_right_y),
                            bbox_color, bbox_thickness)

    # 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
    img_bgr = cv2.putText(img_bgr, bbox_label, (
                            bbox_top_left_x + bbox_labelstr['offset_x'],
                            bbox_top_left_y + bbox_labelstr['offset_y']),
                            cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], bbox_color,
                            bbox_labelstr['font_thickness'])

# 可视化
plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
plt.show()
# 当前目录下保存可视化结果
cv2.imwrite('visualize3.jpg', img_bgr)

二、labelme标注的json文件可视化

# 导入工具包
import cv2
import numpy as np
import json

import matplotlib.pyplot as plt
# matplotlib inline

# 载入图像
img_path = '1.jpg'
img_bgr = cv2.imread(img_path)

# 可视化
# plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
# plt.show()

# 载入labelme格式的json标注文件
labelme_path = '1_labelme.json'

with open(labelme_path, 'r', encoding='utf-8') as f:
    labelme = json.load(f)

# 查看标注信息  rectangle:矩形  point:点  polygon:多边形
# print(labelme.keys())
# dict_keys(['version', 'flags', 'shapes', 'imagePath', 'imageData', 'imageHeight', 'imageWidth'])
# print(labelme['shapes'])

# <<<<<<<<<<<<<<<<<<可视化框(rectangle)标注>>>>>>>>>>>>>>>>>>>>>
# 框可视化配置
bbox_color = (255, 129, 0)           # 框的颜色
bbox_thickness = 5                   # 框的线宽

# 框类别文字
bbox_labelstr = {
    'font_size':6,         # 字体大小
    'font_thickness':14,   # 字体粗细
    'offset_x':0,          # X 方向,文字偏移距离,向右为正
    'offset_y':-80,       # Y 方向,文字偏移距离,向下为正
}
# 画框
for each_ann in labelme['shapes']:  # 遍历每一个标注

    if each_ann['shape_type'] == 'rectangle':  # 筛选出框标注

        # 框的类别
        bbox_label = each_ann['label']
        # 框的两点坐标
        bbox_keypoints = each_ann['points']
        bbox_keypoint_A_xy = bbox_keypoints[0]
        bbox_keypoint_B_xy = bbox_keypoints[1]
        # 左上角坐标
        bbox_top_left_x = int(min(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
        bbox_top_left_y = int(min(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))
        # 右下角坐标
        bbox_bottom_right_x = int(max(bbox_keypoint_A_xy[0], bbox_keypoint_B_xy[0]))
        bbox_bottom_right_y = int(max(bbox_keypoint_A_xy[1], bbox_keypoint_B_xy[1]))

        # 画矩形:画框
        img_bgr = cv2.rectangle(img_bgr, (bbox_top_left_x, bbox_top_left_y), (bbox_bottom_right_x, bbox_bottom_right_y),
                                bbox_color, bbox_thickness)

        # 写框类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
        img_bgr = cv2.putText(img_bgr, bbox_label, (
                              bbox_top_left_x + bbox_labelstr['offset_x'],
                              bbox_top_left_y + bbox_labelstr['offset_y']),
                              cv2.FONT_HERSHEY_SIMPLEX, bbox_labelstr['font_size'], bbox_color,
                              bbox_labelstr['font_thickness'])

# # 可视化
# plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
# plt.show()

# <<<<<<<<<<<<<<<<<<可视化关键点(keypoint)标注>>>>>>>>>>>>>>>>>>>>>
# 关键点的可视化配置
# 关键点配色
kpt_color_map = {
    'angle_30':{'id':0, 'color':[255,0,0], 'radius':30, 'thickness':-1},
    'angle_60':{'id':1, 'color':[0,255,0], 'radius':30, 'thickness':-1},
    'angle_90':{'id':2, 'color':[0,0,255], 'radius':30, 'thickness':-1}
}

# 点类别文字
kpt_labelstr = {
    'font_size':4,             # 字体大小
    'font_thickness':12,       # 字体粗细
    'offset_x':30,             # X 方向,文字偏移距离,向右为正
    'offset_y':100,            # Y 方向,文字偏移距离,向下为正
}

# 画点
for each_ann in labelme['shapes']:  # 遍历每一个标注

    if each_ann['shape_type'] == 'point':  # 筛选出关键点标注

        kpt_label = each_ann['label']  # 该点的类别

        # 该点的 XY 坐标
        kpt_xy = each_ann['points'][0]
        kpt_x, kpt_y = int(kpt_xy[0]), int(kpt_xy[1])

        # 该点的可视化配置
        kpt_color = kpt_color_map[kpt_label]['color']  # 颜色
        kpt_radius = kpt_color_map[kpt_label]['radius']  # 半径
        kpt_thickness = kpt_color_map[kpt_label]['thickness']  # 线宽(-1代表填充)

        # 画圆:画该关键点
        img_bgr = cv2.circle(img_bgr, (kpt_x, kpt_y), kpt_radius, kpt_color, kpt_thickness)

        # 写该点类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
        img_bgr = cv2.putText(img_bgr, kpt_label, (kpt_x + kpt_labelstr['offset_x'], kpt_y + kpt_labelstr['offset_y']),
                              cv2.FONT_HERSHEY_SIMPLEX, kpt_labelstr['font_size'], kpt_color,
                              kpt_labelstr['font_thickness'])

# 可视化
# plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
# plt.show()

# <<<<<<<<<<<<<<<<<<可视化多段线(polygon)标注>>>>>>>>>>>>>>>>>>>>>
# 多段线的可视化配置
poly_color = (151, 57, 224)
poly_thickness = 3

poly_labelstr = {
    'font_size':4,          # 字体大小
    'font_thickness':12,    # 字体粗细
    'offset_x':-200,        # X 方向,文字偏移距离,向右为正
    'offset_y':0,           # Y 方向,文字偏移距离,向下为正
}

# 画多段线
img_mask = np.ones(img_bgr.shape, np.uint8) #创建一个和img_bgr一样大小的黑色mask

for each_ann in labelme['shapes']:  # 遍历每一个标注

    if each_ann['shape_type'] == 'polygon':  # 筛选出多段线(polygon)标注

        poly_label = each_ann['label']  # 该多段线的类别

        poly_points = [np.array(each_ann['points'], np.int32).reshape((-1, 1, 2))]  #reshape后增加一个维度

        # 该多段线平均 XY 坐标,用于放置多段线类别文字
        x_mean = int(np.mean(poly_points[0][:, 0, :][:, 0])) #取出所有点的x坐标并求平均值
        y_mean = int(np.mean(poly_points[0][:, 0, :][:, 1])) #取出所有点的y坐标并求平均值

        # 画该多段线轮廓
        img_bgr = cv2.polylines(img_bgr, poly_points, isClosed=True, color=poly_color, thickness=poly_thickness)

        # 画该多段线内部填充
        img_mask = cv2.fillPoly(img_mask, poly_points, color=poly_color) #填充的颜色为color=poly_color

        # 写该多段线类别文字:图片,文字字符串,文字左上角坐标,字体,字体大小,颜色,字体粗细
        img_bgr = cv2.putText(img_bgr, poly_label,
                              (x_mean + poly_labelstr['offset_x'], y_mean + poly_labelstr['offset_y']),
                              cv2.FONT_HERSHEY_SIMPLEX, poly_labelstr['font_size'], poly_color,
                              poly_labelstr['font_thickness'])

opacity = 0.8 # 透明度,越大越接近原图
img_bgr = cv2.addWeighted(img_bgr, opacity, img_mask, 1-opacity, 0)

# 可视化
plt.imshow(img_bgr[:,:,::-1]) # 将bgr通道转换成rgb通道
plt.show()

# 可视化多段线填充效果
# plt.imshow(img_mask[:, :, ::-1])  # 将bgr通道转换成rgb通道
# plt.show()

# 当前目录下保存可视化结果
cv2.imwrite('visualize1.jpg', img_bgr)

 

 reference

【标注关键点检测数据集】 https://www.bilibili.com/video/BV19g4y1777q/?share_source=copy_web&vd_source=95705b32f23f70b32dfa1721628d5874

猜你喜欢

转载自blog.csdn.net/m0_56247038/article/details/130463548