语义分割mask转json

news2024/12/24 11:39:56

文章目录

    • 1 mask2json ——代码实现
      • 1.1 通过mask获取每个类别对应的灰度值
      • 1.2 mask 转 json
    • 2 mask2json ——利用工具转
      • 2.1支持数据增强
      • 2.2 支持多种格式转换

本文介绍两种语义分割mask转json的方法:

  • 方法1:是参考语义分割mask转json(改进版本), 基于将图像转换为二值图,并利用cv2.findContours来识别轮廓点, 将轮廓点保存为json

  • 方法2:利用github中开源的工具直接转,它支持

1 mask2json ——代码实现

1.1 通过mask获取每个类别对应的灰度值

import os
import cv2
from tqdm import tqdm
 
mask_path = 'mask'
 
data_files = os.listdir(mask_path)
 
# color_list = []
# for data_file in tqdm(data_files):
#     img_file_path = os.path.join(data_path,data_file)
#     img = cv2.imread(img_file_path)
#     for x in range(img.shape[0]):
#         for y in range(img.shape[1]):
#             color = img[x,y]
#             color = list(color)
#             if color not in color_list:
#                 color_list.append(color)
#
#
# print(color_list)
 
gray_list = []
 
for data_file in tqdm(data_files):
    img_file_path = os.path.join(mask_path,data_file)
    img = cv2.imread(img_file_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    for x in range(img.shape[0]):
        for y in range(img.shape[1]):
            value = gray[x,y]
            if value not in gray_list:
                gray_list.append(value)
 
print(gray_list)

1.2 mask 转 json

通过提取灰度图每个类别的像素值得到轮廓信息并转化为json

import cv2
import os
import json
from PIL import Image
import io
import base64
 
# class_dict = {
#     "sky": 10,
#     "building": 0,
#     "column pole": 1,
#     "road": 2,
#     "sidewalk": 3,
#     "tree": 4,
#     "sign symbol": 5,
#     "fence": 6,
#     "car": 7,
#     "pedestrian": 8,
#     "bicyclist": 9
 
# }
 
 
color_list = [128, 0, 0], [0, 0, 244], [255, 96, 0], [240, 0, 0], [255, 212, 0], [0, 212, 255], [0, 100, 255], [74, 255,
                                                                                                                182]
 
gray_list = [15, 73, 85, 27, 154, 201, 135, 213]
 
# def rgb_to_gray_value(RGB):
#     R = RGB[0]
#     G = RGB[1]
#     B = RGB[2]
#     Gray = (R * 299 + G * 587 + B * 114) / 1000
#     return round(Gray)
#
#
# def bgr_2_rgb(color):
#     color[0], color[2] = color[2], color[0]
#     return color
 
 
# class_dict = {
#     "A1 尾胶面破损": rgb_to_gray_value(bgr_2_rgb(color_list[0])),
#     "B1 尾胶少胶": rgb_to_gray_value(bgr_2_rgb(color_list[1])),
#     "C1 尾胶裂": rgb_to_gray_value(bgr_2_rgb(color_list[2])),
#     "E1 骨架破损": rgb_to_gray_value(bgr_2_rgb(color_list[3])),
#     "F1 骨架裂纹": rgb_to_gray_value(bgr_2_rgb(color_list[4])),
#     "G1 尾胶溢胶": rgb_to_gray_value(bgr_2_rgb(color_list[5])),
#     "H1 磁芯": rgb_to_gray_value(bgr_2_rgb(color_list[6])),
# }
 
class_dict = {
    "A1 尾胶面破损": gray_list[0],
    "B1 尾胶少胶": gray_list[1],
    "C1 尾胶裂": gray_list[2],
    "E1 骨架破损": gray_list[3],
    "F1 骨架裂纹": gray_list[4],
    "G1 尾胶溢胶": gray_list[5],
    "H1 磁芯": gray_list[6]
}
 
 
def img_tobyte(img_pil):
    # 类型转换 重要代码
    # img_pil = Image.fromarray(roi)
    ENCODING = 'utf-8'
    img_byte = io.BytesIO()
    img_pil.save(img_byte, format='PNG')
    binary_str2 = img_byte.getvalue()
    imageData = base64.b64encode(binary_str2)
    base64_string = imageData.decode(ENCODING)
    return base64_string
 
 ##########################Mask2json 主函数#####################################
def func(file: str) -> dict:
    if os.path.basename(file) == "0016E5_07959.png":
        print('t')
    png = cv2.imread(file)
    gray = cv2.cvtColor(png, cv2.COLOR_BGR2GRAY)
    img_file_path = os.path.join(img_path, os.path.basename(file).split('.')[0] + '.jpg')
    img = Image.open(img_file_path)
    imgData = img_tobyte(img)
    dic = {"version": "5.1.1", "flags": {}, "shapes": list(), "imagePath": os.path.basename(file), "imageData": imgData,
           "imageHeight": png.shape[0], "imageWidth": png.shape[1]}
    #
    # cv2.imshow("mask", gray)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    for k, v in class_dict.items():
 
        # _, binary = cv2.threshold(gray, v + 1 , 255, cv2.THRESH_TOZERO_INV)
        # _, binary = cv2.threshold(binary, v , 255, cv2.THRESH_BINARY_INV)
        binary = gray.copy()
        binary[binary != v] = 0
        binary[binary == v] = 255
 
        # _, binary = cv2.threshold(gray, i+1, 255, cv2.THRESH_BINARY_INV)
        # _, binary = cv2.threshold(binary, i, 255, cv2.THRESH_TOZERO_INV)
        # _, binary = cv2.threshold(binary, 125, 255, cv2.THRESH_BINARY_INV)
 
        # if os.path.basename(file) == "16729150388540_class3.png":
        # print('t')
        # cv2.imshow('bin', binary)
        # cv2.waitKey(0)
        # cv2.destroyAllWindows()
        # 只检测外轮廓并存储所有的轮廓点
        contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
        for contour in contours:
 
            # img = cv2.imread(img_file_path)
            # cv2.drawContours(img, contour, -1, (0, 0, 255), 3)
            # cv2.imshow("img", img)
            # cv2.waitKey(0)
            # cv2.destroyWindow("img")
            temp = list()
            if len(contour) < 4:
                continue
            for point in contour:
                # if (point[0][0] <  edge_th and point[0][1] < edge_th) or (point[0][0] < edge_th and point[0][1] > png.shape[0] -edge_th) \
                #         or (point[0][0] > png.shape[1] - edge_th and point[0][1] < edge_th) or (point[0][0] > png.shape[1] - edge_th and point[0][1] > png.shape[0] -edge_th):
                #     continue
                # if len(temp) > 1 and temp[-2][0] * temp[-2][1] * int(point[0][0]) * int(point[0][1]) != 0 and (
                #         int(point[0][0]) - temp[-2][0]) * (
                #         temp[-1][1] - temp[-2][1]) == (int(point[0][1]) - temp[-2][1]) * (temp[-1][0] - temp[-1][0]):
                #     temp[-1][0] = int(point[0][0])
                #     temp[-1][1] = int(point[0][1])
                # else:
                temp.append([float(point[0][0]), float(point[0][1])])
            dic["shapes"].append({"label": k, "points": temp, "group_id": None,
                                  "shape_type": "polygon", "flags": {}})
 
    return dic
 
 
if __name__ == "__main__":
    # print(rgb_to_gray_value(bgr_2_rgb(color_list[0])))
    # print(class_dict)
 
    # edge_th = 2
    img_path = 'image'
    mask_path = 'mask'
    save_path = 'json'
    os.makedirs(save_path, exist_ok=True)
 
    mask_files = os.listdir(mask_path)
    for mask_file in mask_files:
        mask_file_path = os.path.join(mask_path, mask_file)
        save_file = mask_file.split('.')[0] + '.json'
        save_file_path = os.path.join(save_path, save_file)
        with open(save_file_path, mode='w', encoding='utf-8') as f:
            json.dump(func(mask_file_path), f)
 

2 mask2json ——利用工具转

github地址:https://github.com/guchengxi1994/mask2json

在这里插入图片描述
该工具支持多种格式转换:

  • 1.augmentation
  • 2.img2xml
  • 3.json2mask
  • 4.json2xml
  • 5.longImgSplit
  • 6.xml2json
  • 7.xml2mask
  • 8.xml2yolo
  • 9.yolo2xml
  • 10.mask2json

2.1支持数据增强

  • (1)image crop supported.(single and multiple crops,rectangle and polygon support. See here)
    在这里插入图片描述
  • (2).image resize supported (auto labeled). See here and the test script is here
    在这里插入图片描述
  • (3) image distortion supported.see here or test-script for details.

2.2 支持多种格式转换

  • xml2yolo
    在这里插入图片描述
  • json2xml
    在这里插入图片描述
  • 其他格式 等等。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/544959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

教你用python的Streamlit库制作可视化网页应用

目录 步骤1&#xff1a;安装 Streamlit步骤2&#xff1a;创建一个新的 Python 文件步骤3&#xff1a;导入必要的库步骤4&#xff1a;编写应用程序代码步骤5&#xff1a;运行应用程序常用组件 当涉及到编写交互式应用程序时&#xff0c;Streamlit 是一个非常流行和强大的 Python…

图神经网络:处理点云

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 简单前置工作学习文献阅读Point的实现模型问题 简单前置工作学…

用项目管理思维来过5·20,真实太酷啦!

明天就是一年一度的520啦&#xff0c;阿道单身多年的同事刚京在四月成功使用SWOT分析模型相亲成功&#xff0c;牵手女嘉宾。二人眼看着就要迎来在一起后的第一个节日520&#xff0c;刚京却因为没有头绪而陷入了不知所措的焦虑。 团队成员齐上阵&#xff0c;用项目管理思维&…

使用 Apache Flink 开发实时 ETL

Apache Flink 是大数据领域又一新兴框架。它与 Spark 的不同之处在于&#xff0c;它是使用流式处理来模拟批量处理的&#xff0c;因此能够提供亚秒级的、符合 Exactly-once 语义的实时处理能力。Flink 的使用场景之一是构建实时的数据通道&#xff0c;在不同的存储之间搬运和转…

<组件封装:Vue + elementUi 通过excel文件实现 “ 批量导入 ” 表单数据,生成对应新增信息 >

Vue elementUi 通过excel文件实现 “ 批量导入 ” 表单数据&#xff0c;生成对应新增信息 &#x1f449; 前言&#x1f449; 一、封装组件对应API及绑定事件> Attributes> Event &#x1f449; 二、实现案例> HTML父组件模板> 子组件模板 &#x1f449; 三、效果演…

线程相关基础知识

一、相关概念 1.1 cpu 中央处理器&#xff08;central processing unit, 简称cpu &#xff09;&#xff0c;计算机系统的 运算 和 控制 核心 1.2 cpu核心数和线程数 cpu核心数指cpu 内核数量&#xff0c;如双核、四核、八核。 cpu线程数是一种逻辑的概念&#xff0c;就是模…

基于 SpringBoot + Redis 实现分布式锁

大家好&#xff0c;我是余数&#xff0c;这两天温习了下分布式锁&#xff0c;然后就顺便整理了这篇文章出来。文末附有源码链接&#xff0c;需要的朋友可以自取。 至于什么是分布式锁&#xff0c;这里不做赘述&#xff0c;不了解的可以自行去查阅资料。 文章目录 实现要点项目…

android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马framework实战

hi,粉丝朋友们! 今天有个学员朋友&#xff0c;问到了一个高斯模糊相关问题&#xff0c;这个高斯模糊相关的需求我相对还是比较熟悉&#xff0c;下面来重点讲解一下新版本高斯模糊相关的实现。 更多framework干货知识手把手教学 Log.i("qq群"&#xff0c;“422901085…

[230528] 托福阅读真题|TPO66 13/30|整卷得分22/30|9:45~10:45|15:40~16:40

The Actor and the Audience P1 rehearsev 排练&#xff1b;排演anticipate v 预期&#xff1b;预料&#xff1b;预见 audiencen 观众brilliantadj 灿烂的&#xff1b;绝妙的rehearsaln 排练&#xff1b;预演&#xff1b;排演crumblev 崩塌stage frightn 怯场&#xff08;演员…

自动化测试框架?这应该是全网最全自动化框架总结了,你要的都有...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

学术加油站|基于LSM-tree存储系统的内存管理,最大限度降低I/O成本

本文系北京理工大学科研助理牛颂登所著&#xff0c;本篇也是 OceanBase 学术系列稿件第 10 篇。欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 「牛颂登&#xff1a;北京理工大学科研助理&#xff0c;硕士期间在电子科技大学网络空间安全研究院从…

资深老鸟总结,Selenium自动化测试实战小技巧,不要再走弯路了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Selenium4自动化测…

数据库小技能:数据报表

文章目录 I 需求1.1 补贴II 实现思路2.1 生成资金调节报表数据III Dto3.1 报表基本查询IV 接口I 需求 代理商调节活动汇总商户调节活动汇总激励金日月汇总数据源:活动流水表(上游回调) 1.1 补贴 调节活动补贴= D0补贴+T1补贴。(比如交易金额满足1000,转T1) 补贴金额 =…

图扑数字孪生智慧灯杆,“多杆合一”降本增效

前言 随着智慧城市建设的不断深入&#xff0c;智慧灯杆作为城市基础设施的重要组成部分&#xff0c;正在成为城市智能化和绿色化的重要手段之一。 效果展示 图扑智慧灯杆系统在城市道路照明领域引入信息化手段&#xff0c;通过构建路灯物联网&#xff0c;实现了现代化的路灯按…

线性代数 --- Gram-Schmidt, 格拉姆-施密特正交化(下)

Gram-Schmidt正交化过程 到目前为止&#xff0c;我们都是在反复强调“对于无解的方程组Axb而言&#xff0c;如果矩阵A是标准正交矩阵的话&#xff0c;就怎么怎么好了。。。。”。因为&#xff0c;不论是求投影还是计算最小二乘的正规方程&#xff0c;他们都包含了。当A为标准正…

yolov4论文解读

数据层面上的数据增强 四张照片拼接成一张进行训练 相当于增大了batch-size&#xff0c;更适合于单GPU。 Mosaic data augmentation 马赛克数据增强 self-adversarial training(SAT) 自我对抗训练 DropBlock Label Smoothing 损失函数 由IOU改进到CIOU 网络结构 CSPNet&…

Win10 WLAN驱动正常但仍然不显示无线网络解决办法

Win10 WLAN驱动正常但仍然不显示无线网络解决办法 写作背景过程解决方案结尾 写作背景 本菜鸡重置了电脑的网络&#xff0c;然后重新启动后 WLAN 不见了&#xff0c;连不了 WIFI 了&#xff0c;很疑惑&#xff0c;后来经过一番搜索找到了问题所在&#xff0c;写下本篇文章以记…

Spark/Flink广播实现作业配置动态更新

前言 在实时计算作业中&#xff0c;往往需要动态改变一些配置&#xff0c;举几个栗子&#xff1a; 实时日志ETL服务&#xff0c;需要在日志的格式、字段发生变化时保证正常解析&#xff1b;实时NLP服务&#xff0c;需要及时识别新添加的领域词与停用词&#xff1b;实时风控服…

访问学者J1签证面签的七个问题

作为访问学者&#xff0c;申请J1签证面签时可能会遇到一些常见问题。下面知识人网小编将介绍七个访问学者面签可能遇到的问题&#xff0c;并提供相应的答案。 问题一&#xff1a;您将在美国进行何种类型的学术研究&#xff1f; 答案&#xff1a;我将在美国从事学术研究&#x…

普冉PY32L020单片机简介,主频最高48MHZ

PY32L020单片机是一颗32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围的 MCU。这颗MCU的价格跟八位单片机相差不大&#xff0c;性价比可以说是非常的高了。来看看PY32L020的配置吧。 PY32L020单片机产品特性&#xff1a; 内核&#xff1a; — 32 位 ARM Cortex - M0 — 最…