【coco】掩膜mask影像转coco格式txt(含python代码)

        最近在做实例分割,遇到二值掩膜影像——coco格式txt的实例分割转换问题,困扰很久,不知道怎么转换,转出来的txt没法用代码成功读取。一系列问题,索性记录下自己的结局路程,方便大家python代码自取。

 


目录

📞📞1.coco格式示例

📗 images模块

📘 categories模块

📙annotation模块

📷📷2.环境准备

📢📢3.maskToanno函数定义

⏰⏰4.images模块内容写入txt

📡📡5.categories模块内容写入txt

🛁🛁6.annotation模块内容写入txt

🔋🔋7.完整python代码

整理不易,欢迎一键三连!!!

送你们一条美丽的--分割线--


📞📞1.coco格式示例

        coco格式txt文件示例:

        主要包含三个模块:

  • images
  • categories
  • annotations

        其中每个模块都由好多个分块组成,images和categories比较简单。

📗 images模块

        images里主要记录的是每张image的长宽,id和文件名信息,注意此处的文件名必须是images文件名,labels也得是相同的文件名,不然索引不到。id从1开始,依次向下编号。

images[
{"height": 512,"width": 512,"id": 1,"file_name": "1.png"
}
...
...
...
{"height": 512,"width": 512,"id": 100,"file_name": "100.png"
}]

📘 categories模块

        categories模块记录的是所有样本的类别信息,name为类别名称,id从1开始,依次向下编号,supercategory表示该类别的从属类别,理解起来比较简单,比如name为bus,supercategory就可以为car,name为cat,supercategory就可以为animal。如果没有多级类别,可以将name和supercategory写出相同的,像我下面写的。

"categories": [
{"supercategory": "land","id": 1,"name": "land"
}
{"supercategory": "land","id": 2,"name": "land2"
}
...
...
...
{"supercategory": "land","id": n,"name": "landn"
}
],

📙annotation模块

         annotation模块主要记录的是label信息,也是最关键的内容,此处以实例分割为例进行讲解,因为coco格式可以做的任务太多,此处仅限实例分割或者语义分割。

annotation模块的一个完整内容包括:

  • segmentation记录目标的边界坐标点位置信息,可以是很长但是要记得是双[[...]];
  • area记录得是目标得面积信息,这个可以自动计算,后面会细讲;
  • iscrowd代表一个目标是否被切分成多块,比如一个猫得身体和尾巴被一只狗头挡住,分开成2部分。0代表没有切分,1代表切分;
  • image_id表示这个目标所对应得原始影像得id编号,与images模块里的id是一一对应的关系;
  • bbox指这个目标的外界矩形框的位置信息;
  • category_id表示这个目标的类别信息,与categories模块里的id是一一对应的关系;
  • id代表目标的编号信息,可以与images个数不一致,因为一张图上很可能会有多个目标。
"annotations": [
{"segmentation": [[276,286,275,287,274,287,273,287,]],"area": 2148,"iscrowd": 0,"image_id": 2,"bbox": [233.0,286.0,49.0,68.0],"category_id": 1,"id": 1
},...{"segmentation": [[276,286,275,287,274,287,273,287,]],"area": 248,"iscrowd": 0,"image_id": 5,"bbox": [233.0,286.0,49.0,68.0],"category_id": 2,"id":100
},

📷📷2.环境准备

        代码所需环境包有:json、numpy、pycocotools、OpenCV、os、sys

        包导入命令:

import jsonimport numpy as npfrom pycocotools import maskimport cv2import osimport sys

📢📢3.maskToanno函数定义

输入:round_truth_binary_mask, ann_count, category_id

输出:annotations

        python代码如下:

def maskToanno(ground_truth_binary_mask, ann_count, category_id):contours, _ = cv2.findContours(ground_truth_binary_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)  # 根据二值图找轮廓annotations = [] #一幅图片所有的annotatonsglobal segmentation_id# print(ann_count)# 对每个实例进行处理for i in range(len(contours)):# print(i)# 生成二值的黑色图片x = np.zeros((512, 512))cv2.drawContours(x, contours, i, (1, 1, 1), -1)  # 将单个mask表示为二值图的形式ground_truth_binary_mask_id = np.array(x, dtype=object).astype(np.uint8)fortran_ground_truth_binary_mask = np.asfortranarray(ground_truth_binary_mask_id)# 求每个mask的面积和框encoded_ground_truth = mask.encode(fortran_ground_truth_binary_mask)ground_truth_area = mask.area(encoded_ground_truth)ground_truth_bounding_box = mask.toBbox(encoded_ground_truth)contour, _ = cv2.findContours(ground_truth_binary_mask_id, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)# contour = measure.find_contours(ground_truth_binary_mask_id, 0.5)# print(contour)annotation = {"segmentation": [],"area": ground_truth_area.tolist(),"iscrowd": 0,"image_id": ann_count,"bbox": ground_truth_bounding_box.tolist(),"category_id": category_id,"id": segmentation_id}#print(contour)# 求segmentation部分contour = np.flip(contour, axis=0)segmentation = contour.ravel().tolist()if len(segmentation)<=4:continueannotation["segmentation"].append(segmentation)annotations.append(annotation)segmentation_id = segmentation_id + 1return annotations

⏰⏰4.images模块内容写入txt

输入:jsonpath

输出:jsonpath

        将jsonpath路径下的txt文件打开,若image存在且对应文件名的label文件存在,就可以写image的images模块信息,python代码如下:

with io.open(jsonPath, 'w', encoding='utf8') as output:# 那就全部写在一个文件夹好了# 先写images的信息output.write(unicode('{\n'))output.write(unicode('"images": [\n'))for image in rgb_image_files:if os.path.exists(os.path.join(block_mask_path, image)):output.write(unicode('{'))annotation = {"height": 512,"width": 512,"id": imageCount,"file_name": image}str_ = json.dumps(annotation, indent=4)str_ = str_[1:-1]if len(str_) > 0:output.write(unicode(str_))imageCount = imageCount + 1if (image == rgb_image_files[-1]):output.write(unicode('}\n'))else:output.write(unicode('},\n'))

📡📡5.categories模块内容写入txt

输入:jsonpath

输出:jsonpath

        将jsonpath路径下的txt文件打开,将categories模块里的supercategory、id、name信息写入txt,此处的categories信息只是示例,可以根据自己的类别信息修改,python代码如下:

with io.open(jsonPath, 'w', encoding='utf8') as output:output.write(unicode('"categories": [\n'))output.write(unicode('{\n'))categories = {"supercategory": "land","id": 1,"name": "land"}str_ = json.dumps(categories, indent=4)str_ = str_[1:-1]if len(str_) > 0:output.write(unicode(str_))output.write(unicode('}\n'))output.write(unicode('],\n'))

🛁🛁6.annotation模块内容写入txt

输入:jsonpath

输出:jsonpath

        将jsonpath路径下的txt文件打开,若label存在且对应文件名的image文件存在,就可以把annotation模块里的信息写入txt,python代码如下:

with io.open(jsonPath, 'w', encoding='utf8') as output:output.write(unicode('"annotations": [\n'))for i in range(len(block_mask_image_files)):if os.path.exists(os.path.join(path, block_mask_image_files[i])):block_image = block_mask_image_files[i]# 读取二值图像block_im = cv2.imread(os.path.join(block_mask_path, block_image), 0)_, block_im = cv2.threshold(block_im, 100, 1, cv2.THRESH_BINARY)if not block_im is None:block_im = np.array(block_im, dtype=object).astype(np.uint8)block_anno = maskToanno(block_im, annCount, 1)for b in block_anno:str_block = json.dumps(b, indent=4)str_block = str_block[1:-1]if len(str_block) > 0:output.write(unicode('{\n'))output.write(unicode(str_block))if (block_image == rgb_image_files[-1] and b == block_anno[-1]):output.write(unicode('}\n'))else:output.write(unicode('},\n'))annCount = annCount + 1else:print(block_image)

🔋🔋7.完整python代码

        二值掩膜mask影像转coco格式的实例分割txt完整python代码如下:

import json
import numpy as np
from pycocotools import mask
import cv2
import os
import sysif sys.version_info[0] >= 3:unicode = strimport io
# 实例的id,每个图像有多个物体每个物体的唯一id
global segmentation_id
segmentation_id = 1
# annotations部分的实现
def maskToanno(ground_truth_binary_mask, ann_count, category_id):contours, _ = cv2.findContours(ground_truth_binary_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)  # 根据二值图找轮廓annotations = [] #一幅图片所有的annotatonsglobal segmentation_id# print(ann_count)# 对每个实例进行处理for i in range(len(contours)):# print(i)# 生成二值的黑色图片x = np.zeros((512, 512))cv2.drawContours(x, contours, i, (1, 1, 1), -1)  # 将单个mask表示为二值图的形式ground_truth_binary_mask_id = np.array(x, dtype=object).astype(np.uint8)fortran_ground_truth_binary_mask = np.asfortranarray(ground_truth_binary_mask_id)# 求每个mask的面积和框encoded_ground_truth = mask.encode(fortran_ground_truth_binary_mask)ground_truth_area = mask.area(encoded_ground_truth)ground_truth_bounding_box = mask.toBbox(encoded_ground_truth)contour, _ = cv2.findContours(ground_truth_binary_mask_id, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)# contour = measure.find_contours(ground_truth_binary_mask_id, 0.5)# print(contour)annotation = {"segmentation": [],"area": ground_truth_area.tolist(),"iscrowd": 0,"image_id": ann_count,"bbox": ground_truth_bounding_box.tolist(),"category_id": category_id,"id": segmentation_id}#print(contour)# 求segmentation部分contour = np.flip(contour, axis=0)segmentation = contour.ravel().tolist()if len(segmentation)<=4:continueannotation["segmentation"].append(segmentation)annotations.append(annotation)segmentation_id = segmentation_id + 1return annotations# mask图像路径
block_mask_path = '/labels_512'
block_mask_image_files = sorted(os.listdir(block_mask_path))# coco json保存的位置
jsonPath = "/data/temp.json"
annCount = 1
imageCount = 1
# 原图像的路径, 原图像和mask图像的名称是一致的。
path = "/images_512"
rgb_image_files = sorted(os.listdir(path))with io.open(jsonPath, 'w', encoding='utf8') as output:# 那就全部写在一个文件夹好了# 先写images的信息output.write(unicode('{\n'))output.write(unicode('"images": [\n'))for image in rgb_image_files:if os.path.exists(os.path.join(block_mask_path, image)):output.write(unicode('{'))annotation = {"height": 512,"width": 512,"id": imageCount,"file_name": image}str_ = json.dumps(annotation, indent=4)str_ = str_[1:-1]if len(str_) > 0:output.write(unicode(str_))imageCount = imageCount + 1if (image == rgb_image_files[-1]):output.write(unicode('}\n'))else:output.write(unicode('},\n'))output.write(unicode('],\n'))# 接下来写cateoutput.write(unicode('"categories": [\n'))output.write(unicode('{\n'))categories = {"supercategory": "land","id": 1,"name": "land"}str_ = json.dumps(categories, indent=4)str_ = str_[1:-1]if len(str_) > 0:output.write(unicode(str_))output.write(unicode('}\n'))output.write(unicode('],\n'))# 写annotationsoutput.write(unicode('"annotations": [\n'))for i in range(len(block_mask_image_files)):if os.path.exists(os.path.join(path, block_mask_image_files[i])):block_image = block_mask_image_files[i]# 读取二值图像block_im = cv2.imread(os.path.join(block_mask_path, block_image), 0)_, block_im = cv2.threshold(block_im, 100, 1, cv2.THRESH_BINARY)if not block_im is None:block_im = np.array(block_im, dtype=object).astype(np.uint8)block_anno = maskToanno(block_im, annCount, 1)for b in block_anno:str_block = json.dumps(b, indent=4)str_block = str_block[1:-1]if len(str_block) > 0:output.write(unicode('{\n'))output.write(unicode(str_block))if (block_image == rgb_image_files[-1] and b == block_anno[-1]):output.write(unicode('}\n'))else:output.write(unicode('},\n'))annCount = annCount + 1else:print(block_image)output.write(unicode(']\n'))output.write(unicode('}\n'))

有问题,欢迎评论区交流~~~

整理不易,欢迎一键三连!!!

送你们一条美丽的--分割线--


🌷🌷🍀🍀🌾🌾🍓🍓🍂🍂🙋🙋🐸🐸🙋🙋💖💖🍌🍌🔔🔔🍉🍉🍭🍭🍋🍋🍇🍇🏆🏆📸📸⛵⛵⭐⭐🍎🍎👍👍🌷🌷

 

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

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

相关文章

DevOps搭建(五)-JDK安装详细步骤

1、官网下载 官方网站下载JDK&#xff0c;这里我们安装JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html 点击上图中的Java SE Downloads项目&#xff0c;也可直接点击下面链接进入&#xff1a; Java Downloads | Oracle 往下滚…

学习Linux(3)-Linux软件安装之yum

什么是yum yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 假设&#xff0c;在一台window系统的电脑上要用qq&#xff0c;那么我们回去下载qq的安装包&#xff0c;然后执行qq.exe文件在本机上进…

10 个顶级 iPhone 数据恢复软件工具评测

很多事情都可能导致 iPhone 数据丢失&#xff1a;iOS 更新失败、越狱错误、解锁问题等。如果您遇到类似情况并且想要访问您的文件&#xff0c;通常最好的解决方案是使用数据恢复工具。由于研究市场上可用的工具可能会花费您大量的时间&#xff08;在尝试从 iPhone 恢复数据时&a…

7.25 SpringBoot项目实战【我的借阅记录】

文章目录 前言一、编写控制器二、编写服务层三、Git提交前言 至此,我们已经实现 图书借阅、收藏、评论等场景,最后来到【还书】场景,首先 还书的 入口 一般 是【我的借阅记录】,在这里可以根据产品设计,对于需要归还的书 操作【还书】,所以本文来实现【我的借阅记录】。…

SAP STMC教程

一、概述 SAP Technical Monitoring Cockpit&#xff08;STMC&#xff09;是SAP最新推出的数据迁移工具&#xff0c;方便在项目部署阶段进行期初数据的导入&#xff0c;是LSMW的小平替&#xff0c;做过LSMW的朋友应该都知道&#xff0c;LSMW步骤比较繁复&#xff0c;并且校验复…

从零开始创建一个项目,springBoot+mybatisPlus+mysql+swagger+maven

一&#xff0c;前提 从零开始创建一个项目&#xff0c;绑定了数据库 用到的技术栈&#xff1a;springBootmybatisPlusmysqlswaggermaven 二&#xff0c;创建项目步骤 1&#xff0c;创建项目 创建出来的项目结构如图所示 2&#xff0c;修改配置文件 因为我比较习惯yml语言&…

Java刷题篇——LeetCode118. 杨辉三角

1.题目描述 给定一个非负整数numRows&#xff0c;生成杨辉三角的前numRows行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例1 输入&#xff1a;numRows 5 输出&#xff1a;[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] 示例2 输入&#xff1a;numRows 1…

如何在 Eolink Apikit 中发起 TCP/UDP 文档测试

TCP/UDP 是两种常用的网络传输协议。TCP 协议提供可靠的连接&#xff0c;而 UDP 协议提供不可靠的连接。 TCP 协议是面向连接的协议&#xff0c;在建立连接之前&#xff0c;客户端和服务器需要先握手。握手完成后&#xff0c;客户端和服务器之间就会建立一个可靠的连接。在连接…

开源协作知识库软件AFFINE如何本地部署并结合内网穿透实现远程访问——“cpolar内网穿透”

前言 本篇文章讲解Notion开源平替全能知识库工具AFFINE如何本地部署&#xff0c;并实现公网远程访问。AFFiNE 是一个全新的开源项目&#xff0c;旨在克服 Notion 和 Miro 在安全和隐私方面的一些局限性。它的设计目标是帮助用户将会议记录、待办事项、文档中的目标、视频会议白…

快速排序的非递归实现

上期我们实现了快速排序的递归实现&#xff0c;但是我们知道如果递归深度太深&#xff0c;栈就会溢出&#xff0c;所以我们本期将为大家讲述快速排序的非递归实现&#xff0c;我们需要用到栈的数据结构&#xff0c;我们知道栈中的数据全是在堆区开辟的空间&#xff0c;堆的空间…

Halcon reduce_domain和scale_image的作用

在Halcon中&#xff0c;reduce_domain是用于缩小图像域&#xff08;Image Domain&#xff09;的操作。 它的作用是通过指定一个感兴趣区域&#xff08;ROI&#xff0c;Region of Interest&#xff09;&#xff0c;将图像数据限制在该区域内&#xff0c;从而实现对图像进行裁剪…

到底什么是DevOps

DevOps不是一组工具&#xff0c;也不是一个特定的岗位。在我看来DevOps更像是一种软件开发文化&#xff0c;一种实现快速交付能力的手段。 DevOps 强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理&#xff0c;从而更快、更频繁地交付更稳定的…

UDP实现群聊

代码&#xff1a; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String;public class liaotian extends JFrame{private static final int DEFAULT_PORT8899;private JLabel stateLB…

基于javaweb实现的实践教学基地管理系统

一、系统架构 前端&#xff1a;html | js | css | bootstrap 后端&#xff1a;spring | springmvc | mybatis-plus 环境&#xff1a;jdk1.8 | mysql8 | tomcat | maven 二、代码及数据库 三、功能介绍 01. web-首页1 02. web-首页2 03. web-首页3 04. web-首页4 05. 管…

【TC3xx】GETH

目录 一、RGMII 二、SMI接口 三、TC3xx MCAL 3.1 MCU 3.2 Port 3.3 DMA 3.4 中断配置 3.5 ETH 3.6 集成 一、RGMII TC3xx支持MII/RMII/RGMII三种以太网数据通信接口。其中RGMII经常用于MAC和MAC之间&#xff0c;或MAC与PHY之间的通信&#xff0c;RGMII的带宽可以是10M…

Soul 推出“SoulX”AI人工智能模型,已应用于旗下 App“苟蛋”AI聊天机器人

Soul社交平台最近发布了名为”SoulX“的AI人工智能模型&#xff0c;SoulX将作为Soul “AIGC社交”布局的重要基建&#xff0c;具备prompt驱动、条件可控生成、上下文理解、多模态理解等能力&#xff0c;垂直应用于平台上多元社交互动场景&#xff0c;如智能对话机器人、AI辅助聊…

为什么越来越多的人从事软件测试行业?

1.市场需求增加&#xff1a;随着数字化转型和互联网的普及&#xff0c;各行各业都需要高质量、稳定可靠的软件来支持其业务运作。因此&#xff0c;对软件测试人员的需求也随之增加。同时&#xff0c;新兴技术的发展&#xff0c;如物联网、大数据、区块链、人工智能等&#xff0…

图纸加密防泄密软件排名

随着科技的不断发展&#xff0c;图纸作为企业的核心资产&#xff0c;其安全性越来越受到重视。为了防止图纸泄露和被非法获取&#xff0c;许多企业开始采用图纸加密防泄密软件来保护自己的核心资产。 本文将介绍一些在市场上广受欢迎的图纸加密防泄密软件&#xff0c;并分析其优…

TSINGSEE青犀中央厨房视频智能监控监管解决方案

一、行业背景 预制菜是指经过洗、切、搭配、加工完成的菜品&#xff0c;采取冷冻或真空等一系列方式进行包装保存&#xff0c;消费者购买后只需通过简单烹调或直接开封即可食用&#xff0c;具有方便、高效、出品稳定的特点。据统计报告分析&#xff0c;从上游食材生产推算以及…

JVM虚拟机系统性学习-JVM相关工具jps、jstat、jinfo、jmap、jhat和jstack

JVM 相关工具 JDK 工具包 jps 查看 Java 进程 jps &#xff1a;列出Java程序进程ID和Main函数名称 jps -q &#xff1a;只输出进程ID jps -m &#xff1a;输出传递给Java进程&#xff08;主函数&#xff09;的参数 jps -l &#xff1a;输出主函数的完整路径 jps -v &#x…