labelme to mask

参考:同济子豪兄:GitHub - TommyZihao/Label2Everything: 常见计算机视觉标注格式相互转换

import os
import json
import numpy as np
import cv2

import matplotlib.pyplot as plt

# 加载图像
img_path = 'uk1.jpeg'
img_bgr = cv2.imread(img_path)
#创建背景
img_mask = np.zeros(img_bgr.shape[:2])
#载入该图像labelme格式的json标注文件
labelme_json_path = 'uk1.json' 
with open(labelme_json_path, 'r', encoding='utf-8') as f:
    labelme = json.load(f)
# 查看该图中的所有标注信息
for each in labelme['shapes']:
    print(each['label'], each['shape_type'])
#每个类别的信息及画mask的顺序(按照由大到小,由粗到精的顺序)
# 0-背景,从 1 开始
class_info = [
    {'label':'sky', 'type':'polygon', 'color':1},                    # polygon 多段线
    {'label':'road', 'type':'polygon', 'color':2},
    {'label':'building', 'type':'polygon', 'color':3},
    {'label':'tower','type':'polygon','color':4},
    {'label':'bus','type':'polygon','color':5},
    {'label':'car','type':'polygon','color':6},
    {'label':'tree','type':'polygon','color':7},
    {'label':'fence','type':'polygon','color':8},
    {'label':'wall','type':'polygon','color':9},
    {'label':'person','type':'polygon','color':10},
    {'label':'clock', 'type':'circle', 'color':11, 'thickness':-1},   # circle 圆形,-1表示填充
    {'label':'lane', 'type':'line', 'color':12, 'thickness':5},       # line 两点线段,填充线宽
    {'label':'sign', 'type':'linestrip', 'color':13, 'thickness':3}   # linestrip 多段线,填充线宽
]
按顺序将mask绘制在空白图上
for one_class in class_info: # 按顺序遍历每一个类别
    for each in labelme['shapes']: # 遍历所有标注,找到属于当前类别的标注
        if each['label'] == one_class['label']:
            if one_class['type'] == 'polygon': # polygon 多段线标注
                
                # 获取点的坐标
                points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
                
                # 在空白图上画 mask(闭合区域)
                img_mask = cv2.fillPoly(img_mask, points, color=one_class['color'])
                
            elif one_class['type'] == 'line' or one_class['type'] == 'linestrip': # line 或者 linestrip 线段标注
                
                # 获取点的坐标
                points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
                
                # 在空白图上画 mask(非闭合区域)
                img_mask = cv2.polylines(img_mask, points, isClosed=False, color=one_class['color'], thickness=one_class['thickness']) 
            
            elif one_class['type'] == 'circle': # circle 圆形标注
                
                points = np.array(each['points'], dtype=np.int32)
                
                center_x, center_y = points[0][0], points[0][1] # 圆心点坐标
                
                edge_x, edge_y = points[1][0], points[1][1]     # 圆周点坐标
                
                radius = np.linalg.norm(np.array([center_x, center_y] - np.array([edge_x, edge_y]))).astype('uint32') # 半径
                
                img_mask = cv2.circle(img_mask, (center_x, center_y), radius, one_class['color'], one_class['thickness'])
            
            else:
                print('未知标注类型', one_class['type'])
plt.imshow(img_mask)
plt.show()

# 保存mask标注图像(必须是png格式)
mask_path = img_path.split('.')[0] + '.png'
cv2.imwrite(mask_path, img_mask)
# 载入mask标注图像
mask_img = cv2.imread('uk1.png')

批量操作

# 查看数据集目录结构
import seedir as sd
sd.seedir('Watermelon87_Semantic_Seg_Labelme', style='emoji', depthlimit=1)

📁 Watermelon87_Semantic_Seg_Labelme/
├─📁 images/
└─📁 labelme_jsons/
 

删除系统自动生成的多余文件
查看待删除的多余文件
!find . -iname '__MACOSX'
!find . -iname '.DS_Store'
!find . -iname '.ipynb_checkpoints'
./.ipynb_checkpoints
删除多余文件
!for i in `find . -iname '__MACOSX'`; do rm -rf $i;done
!for i in `find . -iname '.DS_Store'`; do rm -rf $i;done
!for i in `find . -iname '.ipynb_checkpoints'`; do rm -rf $i;done
验证多余文件已删除
!find . -iname '__MACOSX'
!find . -iname '.DS_Store'
!find . -iname '.ipynb_checkpoints'

进入数据集目录

import os
import json
import numpy as np
import cv2
import shutil

from tqdm import tqdm
Dataset_Path = 'Watermelon87_Semantic_Seg_Labelme'

每个类别的信息及画mask的顺序(按照由大到小,由粗到精的顺序)

# 0-背景,从 1 开始
class_info = [
    {'label':'red', 'type':'polygon', 'color':1},                    # polygon 多段线
    {'label':'green', 'type':'polygon', 'color':2},
    {'label':'white', 'type':'polygon', 'color':3},
    {'label':'seed-black','type':'polygon','color':4},
    {'label':'seed-white','type':'polygon','color':5}
]

单张图像labelme转mask函数

def labelme2mask_single_img(img_path, labelme_json_path):
    '''
    输入原始图像路径和labelme标注路径,输出 mask
    '''
    
    img_bgr = cv2.imread(img_path)
    img_mask = np.zeros(img_bgr.shape[:2]) # 创建空白图像 0-背景
    
    with open(labelme_json_path, 'r', encoding='utf-8') as f:
        labelme = json.load(f)
        
    for one_class in class_info: # 按顺序遍历每一个类别
        for each in labelme['shapes']: # 遍历所有标注,找到属于当前类别的标注
            if each['label'] == one_class['label']:
                if one_class['type'] == 'polygon': # polygon 多段线标注

                    # 获取点的坐标
                    points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]

                    # 在空白图上画 mask(闭合区域)
                    img_mask = cv2.fillPoly(img_mask, points, color=one_class['color'])

                elif one_class['type'] == 'line' or one_class['type'] == 'linestrip': # line 或者 linestrip 线段标注

                    # 获取点的坐标
                    points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]

                    # 在空白图上画 mask(非闭合区域)
                    img_mask = cv2.polylines(img_mask, points, isClosed=False, color=one_class['color'], thickness=one_class['thickness']) 

                elif one_class['type'] == 'circle': # circle 圆形标注

                    points = np.array(each['points'], dtype=np.int32)

                    center_x, center_y = points[0][0], points[0][1] # 圆心点坐标

                    edge_x, edge_y = points[1][0], points[1][1]     # 圆周点坐标

                    radius = np.linalg.norm(np.array([center_x, center_y] - np.array([edge_x, edge_y]))).astype('uint32') # 半径

                    img_mask = cv2.circle(img_mask, (center_x, center_y), radius, one_class['color'], one_class['thickness'])

                else:
                    print('未知标注类型', one_class['type'])
                    
    return img_mask

labelme转mask-批量

os.chdir(Dataset_Path)
os.mkdir('masks')
os.chdir('images')

for img_path in tqdm(os.listdir()):
    
    try:
    
        labelme_json_path = os.path.join('../', 'labelme_jsons', '.'.join(img_path.split('.')[:-1])+'.json')

        img_mask = labelme2mask_single_img(img_path, labelme_json_path)

        mask_path = img_path.split('.')[0] + '.png'

        cv2.imwrite(os.path.join('../','masks',mask_path), img_mask)
    
    except Exception as E:
        print(img_path, '转换失败', E)

 

转换之后的mask保存在masks文件夹中

重命名和删除文件夹

os.chdir('../')
shutil.move('images', 'img_dir')
shutil.move('masks', 'ann_dir')

!rm -rf labelme_jsons

os.chdir('../')
 

得到最终的语义分割数据集

查看数据集目录结构

 

import seedir as sd
sd.seedir('Watermelon87_Semantic_Seg_Labelme', style='emoji', depthlimit=1)
📁 Watermelon87_Semantic_Seg_Labelme/
├─📁 img_dir/
└─📁 ann_dir/

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值