IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 目标检测数据集的介绍与修改 -> 正文阅读

[人工智能]目标检测数据集的介绍与修改

数据集介绍

VOC 格式

voc 形式的数据集一般包含以下几个文件夹

  • Annotations
  • ImageSets
  • JPEGImages
  • SegmentationClass
  • SegmentationObject

对于目标检测的任务而言,一般只需要用到 Annotations 文件夹和 JPEGImages 文件夹,其中测试图片和训练图片都保存在一个目录下面,通过 ImageSets 文件夹中 Main 子文件夹下面的 txt 文件来对测试图片和验证图片进行解析。

JPEGImages 主要提供的是PASCAL VOC所提供的所有的图片信息,包括训练图片,测试图片,这些图像就是用来进行训练和测试验证的图像数据。

Annotations 主要存放 xml 格式的标签文件,每个 xml 对应 JPEGImage 中的一张图片

ImageSetsMain 图像物体识别的数据,总共 20 类, 需要保证 train、val 没有交集

SegmentationObject & SegmentationClass?保存的是物体分割后的数据,在物体识别中没有用到

<annotation>  
    <folder>VOC2012</folder>  // 图像所在文件夹                             
    <filename>2007_000392.jpg</filename>  // 文件名  
    <source>   // 图像来源(不重要)  
        <database>The VOC2007 Database</database>  
        <annotation>PASCAL VOC2007</annotation>  
        <image>flickr</image>  
    </source>  
    <size>  // 图像尺寸(长宽以及通道数)                        
        <width>500</width>  
        <height>332</height>  
        <depth>3</depth>  
    </size>  
    <segmented>1</segmented>  // 是否用于分割(在图像物体识别中01无所谓)  
    <object>  // 目标对象的信息
        <name>horse</name>  // 物体类别  
        <pose>Right</pose>  // 拍摄角度  
        <truncated>0</truncated>  // 是否被截断(0表示完整)  
        <difficult>0</difficult> // 目标是否难以识别(0表示容易识别)  
        <bndbox>  // bounding-box 边界框信息(包含左下角和右上角xy坐标)  
            <xmin>100</xmin>  
            <ymin>96</ymin>  
            <xmax>355</xmax>  
            <ymax>324</ymax>  
        </bndbox>  
    </object>  
    <object>  // 下面是其他目标的信息,这里略掉
        ......
    </object>  
</annotation> 

一般而言,有图片的名称、长和宽等信息,之后一张图片对应有多个 object,每个 object 中包含了类名、然后三个对于目标检测而言不重要的信息,以及 bndbox 信息,bndbox 信息十分重要,主要是左上角的坐标和右下角的坐标。

COCO格式

coco 数据集为 json 文件,一般包含5个字段

  • info
  • images
  • annotations
  • licenses
  • categories

info

info 字段包含了数据集的基本信息,包括数据集的来源,提供者之类的,info 字段在写程序的时候一般不会使用到,内容如下:

info: {
    "year": int,  # 年份
    "version": str,  # 版本
    "description": str,  # 数据集描述
    "contributor": str,  # 提供者
    "url": str,  # 下载地址
    "date_created": datetime
}

licenses

licenses 字段表明了图片的版权信息之类的,一般的程序中也用不到,licenses字段的结构如下:

license{
    "id": int,
    "name": str,
    "url": str,
} 

images

images 字段是整个 json 文件中最重要的字段之一,包含了图片的基本信息,包括图片的名称,宽高。images 目录由多个 image 构成数组,可以遍历。每一个 image 的实例是一个 dict。其中有一个 id 字段,代表的是图片的 id,每一张图片具有唯一的一个独特的 id。结构如下:

image{
    "id": int,  # 图片的ID编号(每张图片ID是唯一的)
    "width": int,  # 宽
    "height": int,  # 高
    "file_name": str,  # 图片名
    "license": int,
    "flickr_url": str,  # flickr网路地址
    "coco_url": str,  # 网路地址路径
    "date_captured": datetime  # 数据获取日期
}

annotations

annotations 存储图片的标注信息,结构如下:

annotation{
    "id": int,  # 对象ID,因为每一个图像有不止一个对象,所以要对每一个对象编号(每个对象的ID是唯一的)
    "image_id": int,  # 对应的图片ID(与images中的ID对应)
    "category_id": int,  # 类别ID(与categories中的ID对应)
    "segmentation": RLE or [polygon],  # 对象的边界点(边界多边形,此时iscrowd=0)。
    # segmentation 格式取决于这个实例是一个单个的对象(即iscrowd=0,将使用polygons格式)还是一组对象(即iscrowd=1,将使用RLE格式)
    "area": float,  # 区域面积
    "bbox": [x,y,width,height],  # 定位边框 [x,y,w,h]
    "iscrowd": 0 or 1  # 见下
}

其中注意这里的bbox格式为[x,y,width,height]。[x,y,w,h]是没有进行归一化的,所以在进行yolo的转化时需要进行归一化的处理。

categories

categories字段是记录annotations字段中的类别信息,结构如下:

{
	"supercategory": str,  # 主类别
    "id": int,  # 类对应的id (0 默认为背景)
    "name": str  # 子类别
}

YOLO数据集格式

yolo标注格式保存在.txt文件中,一共5个数据,用空格隔开,举例说明如下图所示:

若图像的高和宽别为h,w,bbox的左上角坐标为(x1, y2),右下角坐标为(x2, y2),则bbox中心坐标(x_c, y_c)为:x_c = x1 + (x2 - x1)/2 = (x1 + x2)/2;y_c = y1 + (y2 - y1)/2 = (y1 + y2)/2

假设yolo的5个数据分别为:label, x_, y_, w_, h_,则有对应关系:

x_ = (x1 + x2) / 2w;y_ = (y1 + y2) / 2h;w_ = (x2 - x1) / w;h_ = (y2 - y1) / h

反过来,则有:

x1 = w * x_ - 0.5 * w * w_;x2 = w * x_ + 0.5 * w * w_
y1 = h * y_ - 0.5 * h * h_;y2 = h * y_ + 0.5* h * h_

批量修改XML标注文件标签名

"""
使用python xml解析树解析xml文件,批量修改xml文件里object节点下name节点的text
"""

import glob
import xml.etree.ElementTree as ET
path = r'D:\Software\OneDrive\桌面\吊弓'    # xml文件夹路径
for xml_file in glob.glob(path + '/*.xml'):
    tree = ET.parse(xml_file)
    obj_list = tree.getroot().findall('object')
    for per_obj in obj_list:
        if per_obj[0].text == '吊弓':    # 待修改的标签名
            per_obj[0].text = 'flaw'    # 欲修改成的标签名
            i = i+1
    tree.write(xml_file)    # 将改好的文件重新写入,会覆盖原文件

?

天池布匹瑕疵竞赛数据集格式转换(json —> yolo)

?只检测疵点并不对疵点进行具体的分类

import numpy as np # linear algebra
import os
import json
from tqdm.auto import tqdm
import shutil as sh
import cv2
# 标签json存放地址
josn_path = r".\Annotations\annp_train.json"
# 图片存放地址
image_path = r".\images"

name_list = []
image_h_list = []
image_w_list = []
c_list = []  # defect_name
w_list = []
h_list = []
x_center_list = []  # bbox中心坐标
y_center_list = []
'''
    with 语句用于异常处理,封装了 try…except…finally 编码范式,提高了易用性。
    open(name[, mode[, buffering]])
	    name:包含待访问的文件名称的字符串值
	    mode:决定了打开文件的模式:只读,写入,追加等。参数非强制,默认文件访问模式为只读(r)。
    tqdm模块是python进度条库
'''
with open(josn_path, 'r') as f:
    temps = tqdm(json.loads(f.read()))  # 默认读取整个文件
    for temp in temps:
        # image_w = temp["image_width"]
        # image_h = temp["image_height"]
        '''
            str.split("[")[1]. split("]")[0]输出的是 [ 后的内容以及 ] 前的内容。
	        str.split("[")[1]. split("]")[0]. split(".") 是先输出 [ 后的内容以及 ] 前的内容,然后通过 . 作为分	    隔符对字符串进行切片。
        '''
        name = temp["name"].split('.')[0]  # 字典
        path = os.path.join(image_path, temp["name"])
        print('path: ',path)
        im = cv2.imread(path)
        sp = im.shape  # shape函数可以读取矩阵的形状(高宽通道)
        image_h, image_w = sp[0], sp[1]
        # print("image_h, image_w: ", image_h, image_w)
        # print("defect_name: ",temp["defect_name"])
        #bboxs
        x_l, y_l, x_r, y_r = temp["bbox"]
        # print(temp["name"], temp["bbox"])
        if temp["defect_name"]=="沾污":
            defect_name = '0'
        elif temp["defect_name"]=="错花":
            defect_name = '0'
        elif temp["defect_name"] == "水印":
            defect_name = '0'
        elif temp["defect_name"] == "花毛":
            defect_name = '0'
        elif temp["defect_name"] == "缝头":
            defect_name = '0'
        elif temp["defect_name"] == "缝头印":
            defect_name = '0'
        elif temp["defect_name"] == "虫粘":
            defect_name = '0'
        elif temp["defect_name"] == "破洞":
            defect_name = '0'
        elif temp["defect_name"] == "褶子":
            defect_name = '0'
        elif temp["defect_name"] == "织疵":
            defect_name = '0'
        elif temp["defect_name"] == "漏印":
            defect_name = '0'
        elif temp["defect_name"] == "蜡斑":
            defect_name = '0'
        elif temp["defect_name"] == "色差":
            defect_name = '0'
        elif temp["defect_name"] == "网折":
            defect_name = '0'
        elif temp["defect_name"] == "其他":
            defect_name = '0'
        else:
            defect_name = '0'
            # print("----------------------------------error---------------------------")
            # raise("erro")  # 主动抛出异常
        # print(image_w, image_h)
        # print(defect_name)
        x_center = (x_l + x_r)/(2*image_w)
        y_center = (y_l + y_r)/(2*image_h)
        w = (x_r - x_l)/(image_w)
        h = (y_r - y_l)/(image_h)
        # print(x_center, y_center, w, h)
        name_list.append(temp["name"])
        c_list.append(defect_name)
        image_h_list.append(image_w)
        image_w_list.append(image_h)
        x_center_list.append(x_center)
        y_center_list.append(y_center)
        w_list.append(w)
        h_list.append(h)

    index = list(set(name_list))  # set() 函数创建一个无序不重复元素集,list() 将元组转换为列表。
    # print(len(index))
    fold = 0
    # for fold in [0]:
    val_index = index[len(index) * fold // 5:len(index) * (fold + 1) // 5]  # //整数除法
    # list2[1:5]:  [2, 3, 4, 5]
    # print(len(val_index))
    # enumerate() 用于将一个可遍历的数据对象(如列表、元组)组合为一个索引序列,同时列出数据和数据下标
    for num, name in enumerate(name_list):
        # print(c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num])
        row = [c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num]]
        if name in val_index:
            path2save = 'val/'
        else:
            path2save = 'train/'
        # print('convertor\\fold{}\\labels\\'.format(fold) + path2save)
        # print('convertor\\fold{}/labels\\'.format(fold) + path2save + name.split('.')[0] + ".txt")
        # print("{}/{}".format(image_path, name))
        # print('convertor\\fold{}\\images\\{}{}'.format(fold, path2save, name))
        if not os.path.exists('convertor/fold{}/labels/'.format(fold) + path2save):
            os.makedirs('convertor/fold{}/labels/'.format(fold) + path2save)
        with open('convertor/fold{}/labels/'.format(fold) + path2save + name.split('.')[0] + ".txt", 'a+') as f:
            for data in row:
                f.write('{} '.format(data))
            f.write('\n')
            if not os.path.exists('convertor/fold{}/images/{}'.format(fold, path2save)):
                os.makedirs('convertor/fold{}/images/{}'.format(fold, path2save))
            # print(os.path.join(image_path, name))
            # print('convertor/fold{}/images/{}/{}'.format(fold, path2save, name))
            sh.copy(os.path.join(image_path, name),
                    'convertor/fold{}/images/{}/{}'.format(fold, path2save, name))

待续。。

参考文章

批量修改XML标注文件标签(label)名称_SYGgogogo的博客-CSDN博客

目标检测常用数据集格式转化voc yolo coco_dejahu的博客-CSDN博客_常用数据集格式

目标检测常用数据集格式 - 知乎 (zhihu.com)

YOLO数据格式说明与转换_lokvke的博客-CSDN博客_yolo数据格式

team-learning-cv/DefectDetection at master · datawhalechina/team-learning-cv · GitHub

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:30:27  更:2022-03-12 17:34:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:28:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码