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

2023-12-14 19:28

本文主要是介绍【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'))

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

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

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


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

 

这篇关于【coco】掩膜mask影像转coco格式txt(含python代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/493696

相关文章

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑