草庐IT

快速制作自己的VOC语义分割数据集

炼丹代师 2023-04-09 原文

语义分割数据集制作与转换方法

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
第一章 基于PS的语义分割标注
第二章 构建VOC语义分割数据集


文章目录


前言

PASCAL VOC2012数据集简介

PASCAL VOC2012是语义分割任务极为重要的官方数据集,大量优秀的语义分割模型都会刷一下这个数据集,因此我们在使用别人的开源代码时,如果能将自己的数据集整理成官方数据集的格式,则可快速验证模型性能,减少自身工作量。
VOC2012官方数据集文件结构共包含五个文件夹

其中语义分割需要的包括:
1.ImageSets/Segmentation:存放训练验证集文件名称的txt文件;

2.JPEGImages:存放原始图像的文件夹

3.SegmentationClass:存放标注文件的文件夹

因此,在制作自己数据集时,只需保证这三个文件夹的内容统一,即可完成数据集制作。


一、构建文件夹

根据上述的文件夹结构,创建VOC2012文件夹,在VOC2012内创建ImageSets文件夹、JPEGImages文件夹、SegmentationClass文件夹,在ImageSets文件夹内创建Segmentation文件夹。


二、移动图片

将自己数据集的原始图片移动到JPEGImages文件夹下,将自己数据集的标注图片移动到SegmentationClass文件夹下。
PS标注工具的使用请移步至:【PS才是真科研利器,助力快速分割标注工作】

三、生成TXT文件

这里提供一段代码:可自动生成train.txt、val.txt、trainval.txt,并检查图像与标注图像长宽维度是否一致、标注图像是否为二维图像、并生成数据集均值、方差及各类别像素比例

import mmcv
import os
import os.path as osp
import random
"""1.检查图像维度"""
import numpy as np
from PIL import Image,ImageOps
from torchvision import transforms


def get_Image_dim_len(png_dir: str,jpg_dir:str):
    png = Image.open(png_dir)
    png_w,png_h=png.width,png.height
    #若第十行报错,说明jpg图片没有对应的png图片
    png_dim_len = len(np.array(png).shape)
    assert png_dim_len==2,"提示:存在三维掩码图"
    jpg=Image.open(jpg_dir)
    jpg = ImageOps.exif_transpose(jpg)
    jpg.save(jpg_dir)
    jpg_w,jpg_h=jpg.width,jpg.height
    print(jpg_w,jpg_h,png_w,png_h)
    assert png_w==jpg_w and png_h==jpg_h,print("提示:%s mask图与原图宽高参数不一致"%(png_dir))


"""2.读取单个图像均值和方差"""
def pixel_operation(image_path: str):
    img = cv.imread(image_path, cv.IMREAD_COLOR)
    means, dev = cv.meanStdDev(img)
    return means,dev

"""3.分割数据集,生成label文件"""
# 原始数据集 ann上一级
data_root = 'VOC2012'
#图像地址
image_dir="JPEGImages"
# ann图像文件夹
ann_dir = "SegmentationClass"
# txt文件保存路径
split_dir = 'ImageSets/Segmentation'
mmcv.mkdir_or_exist(osp.join(data_root, split_dir))

png_filename_list = [osp.splitext(filename)[0] for filename in mmcv.scandir(
    osp.join(data_root, ann_dir), suffix='.png')]
jpg_filename_list=[osp.splitext(filename)[0] for filename in mmcv.scandir(
    osp.join(data_root, image_dir), suffix='.jpg')]
assert len(jpg_filename_list)==len(png_filename_list),"提示:原图与掩码图数量不统一"
print("数量检查无误")
for i in range(10):
   random.shuffle(jpg_filename_list)
red_num=0
black_num=0
with open(osp.join(data_root, split_dir, 'trainval.txt'), 'w+') as f:
    length = int(len(jpg_filename_list))
    for line in jpg_filename_list[:length]:
        pngpath=osp.join(data_root,ann_dir,line+'.png')
        jpgpath=osp.join(data_root,image_dir,line+'.jpg')
        get_Image_dim_len(pngpath,jpgpath)
        img=cv.imread(pngpath,cv.IMREAD_GRAYSCALE)
        red_num+=len(img)*len(img[0])-len(img[img==0])
        black_num+=len(img[img==0])
        f.writelines(line + '\n')
    value=red_num/black_num

train_mean,train_dev=[[0.0,0.0,0.0]],[[0.0,0.0,0.0]]
with open(osp.join(data_root, split_dir, 'train.txt'), 'w+') as f:
    train_length = int(len(jpg_filename_list) * 7/ 10)
    for line in jpg_filename_list[:train_length]:
        jpgpath=osp.join(data_root,image_dir,line+'.jpg')
        mean,dev=pixel_operation(jpgpath)
        train_mean+=mean
        train_dev+=dev
        f.writelines(line + '\n')
with open(osp.join(data_root, split_dir, 'val.txt'), 'w+') as f:
    for line in jpg_filename_list[train_length:]:
        jpgpath=osp.join(data_root,image_dir,line+'.jpg')
        mean,dev=pixel_operation(jpgpath)
        train_mean+=mean
        train_dev+=dev
        f.writelines(line + '\n')
    train_mean,train_dev=train_mean/length, train_dev /length

doc=open('均值方差像素比.txt','a+')
doc.write("均值:"+'\n')
for item in train_mean:
    doc.write(str(item[0])+'\n')
doc.write("训练集方差:"+'\n')
for item in train_dev:
    doc.write(str(item[0])+'\n')
doc.write("像素比:"+'\n')
doc.write(str(value))
train_mean,train_dev=[[0.0,0.0,0.0]],[[0.0,0.0,0.0]]

运行完上述代码后,在VOC2012文件夹下便可看到均值方差像素比.txt文件:

同时,三个标签引索txt文件也随之生成:

总结

提示:这里对文章进行总结:

本文介绍了如何构建自己的VOC数据集。以供大家交流讨论!
往期回顾:
(1)CBAM论文解读+CBAM-ResNeXt的Pytorch实现
(2)SENet论文解读及代码实例
(3)ShuffleNet-V1论文理解及代码复现
(4) ShuffleNet-V2论文理解及代码复现
(5)GhostNet论文理解及代码复现
(6)PS才是真科研利器,助力快速分割标注工作
下期预告:
VOC数据集的使用–如何根据自己的数据集实现mmsegmentation算法库任意语义分割算法

有关快速制作自己的VOC语义分割数据集的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  3. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  8. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  9. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  10. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

随机推荐