分割数据集label转换为目标检测boundingbox

实现功能

将分割的label图转换为目标检测boundingbox标注文件(VOC格式)。

注:

1.分割样本里一张图片只有同一类别的多个目标。

2.转换为boundingbox标注通过连通域实现,所以重叠的目标处理不了,会标为1个

数据集格式

其中,语义分割数据集格式如下:

原图片在JPEGImages文件夹中,命名格式为ImageID.jpg

    

Label图在labelimage文件夹中,命名格式为ImageID_classname.png

     

生成的boundingbox标注命名格式为ImageID.xml

   

XML标注格式

<annotation>
   <folder>road_dataset</folder>                      #文件名
   <filename>3425.jpg</filename>                      #原图片名
   <path>D:\road_dataset\JPEGImages\3425.jpg</path>   #原图片地址
   <source>
      <database>Unknown</database>
   </source>
   <size>                               #图片尺寸
      <width>512</width>
      <height>512</height>
      <depth>3</depth>
   </size>
   <segmented>0</segmented>            #是否用于分割,0为否
   <object>                            #目标
      <name>butt</name>                #类别名称
      <pose>Unspecified</pose>         #拍摄角度
      <truncated>0</truncated>         #是否被截断
      <difficult>0</difficult>         #是否为困难样本
      <bndbox>                         #boundingbox坐标(左下、右上)
         <xmin>327</xmin>
         <ymin>38</ymin>
         <xmax>394</xmax>
         <ymax>69</ymax>
      </bndbox>
   </object>
   <object>                             #多个目标
      <name>Cigarette butts</name>
      <pose>Unspecified</pose>
      <truncated>0</truncated>
      <difficult>0</difficult>
      <bndbox>
         <xmin>139</xmin>
         <ymin>279</ymin>
         <xmax>214</xmax>
         <ymax>318</ymax>
      </bndbox>
   </object>
</annotation>

其中<pose>  <truncated> <difficult> 全是默认值。

得到label图中的连通域

使用skimage的morphology, measure通过连通域得到每一副一幅图片上的目标数量和boundingbox。

import os
import numpy as np
from itertools import groupby
from skimage import morphology,measure
from PIL import Image
from scipy import misc

# 因为一张图片里只有一种类别的目标,所以label图标记只有黑白两色
rgbmask = np.array([[0,0,0],[255,255,255]],dtype=np.uint8)

# 从label图得到 boundingbox 和图上连通域数量 object_num
def getboundingbox(image):
    # mask.shape = [image.shape[0], image.shape[1], classnum]
    mask = np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8)
    mask[np.where(np.all(image == rgbmask[1],axis=-1))[:2]] = 1
    # 删掉小于10像素的目标
    mask_without_small = morphology.remove_small_objects(mask,min_size=10,connectivity=2)
    # 连通域标记
    label_image = measure.label(mask_without_small)
    #统计object个数
    object_num = len(measure.regionprops(label_image))
    boundingbox = list()
    for region in measure.regionprops(label_image):  # 循环得到每一个连通域bbox
        boundingbox.append(region.bbox)
    return object_num, boundingbox

在label图片上显示boundingbox,查看结果:

import matplotlib.pyplot as plt
import matplotlib.patches as patch

# 输出成图片查看得到boundingbox效果
imagedir = r‘D:\test_dataset\labelimage‘

if ~os.path.exists(r‘D:\test_dataset\test_getbbox‘):
    os.mkdir(r‘D:\test_dataset\test_getbbox‘)
for root, _, fnames in sorted(os.walk(imagedir)):
    for fname in sorted(fnames):
        imagepath = os.path.join(root, fname)
        image = misc.imread(imagepath)
        objectnum, bbox = getboundingbox(image)
        ImageID = fname.split(‘.‘)[0]

        fig,ax = plt.subplots(1)
        ax.imshow(image)
        for box in bbox:
            rect = patch.Rectangle((box[1], box[0]), box[3]-box[1], box[2]-box[0],edgecolor = ‘r‘, linewidth = 1,fill = False)
            ax.add_patch(rect)
        plt.savefig(‘D:/test_dataset/test_getbbox/‘+ImageID+‘.png‘)

输出图像为:

生成XML标注文件

createXMLlabel: 根据标注信息生成XML标注文件
import xml.etree.ElementTree as ET

def createXMLlabel(savedir,objectnum, bbox, classname, foldername=‘0‘,filename=‘0‘, path=‘0‘, database=‘road‘, width=‘400‘, height=‘600‘,depth=‘3‘, segmented=‘0‘, pose="Unspecified", truncated=‘0‘, difficult=‘0‘):
    # 创建根节点
    root = ET.Element("annotation")

    # 创建子节点
    folder_node = ET.Element("folder")
    folder_node.text = foldername
    # 将子节点数据添加到根节点
    root.append(folder_node)

    file_node = ET.Element("filename")
    file_node.text = filename
    root.append(file_node)
    path_node = ET.Element("path")
    path_node.text = path
    root.append(path_node)

    source_node = ET.Element("source")
    # 也可以使用SubElement直接添加子节点
    db_node = ET.SubElement(source_node, "database")
    db_node.text = database
    root.append(source_node)

    size_node = ET.Element("size")
    width_node = ET.SubElement(size_node, "width")
    height_node = ET.SubElement(size_node, "height")
    depth_node = ET.SubElement(size_node, "depth")
    width_node.text = width
    height_node.text = height
    depth_node.text = depth
    root.append(size_node)

    seg_node = ET.Element("segmented")
    seg_node.text = segmented
    root.append(seg_node)

    for i in range(objectnum):
        newEle = ET.Element("object")
        name = ET.Element("name")
        name.text = classname
        newEle.append(name)
        pose_node = ET.Element("pose")
        pose_node.text = pose
        newEle.append(pose_node)
        trunc = ET.Element("truncated")
        trunc.text = truncated
        newEle.append(trunc)
        dif = ET.Element("difficult")
        dif.text = difficult
        newEle.append(dif)
        boundingbox = ET.Element("bndbox")
        xmin = ET.SubElement(boundingbox, "xmin")
        ymin = ET.SubElement(boundingbox, "ymin")
        xmax = ET.SubElement(boundingbox, "xmax")
        ymax = ET.SubElement(boundingbox, "ymax")
        xmin.text = str(bbox[i][1])
        ymin.text = str(bbox[i][0])
        xmax.text = str(bbox[i][3])
        ymax.text = str(bbox[i][2])
        newEle.append(boundingbox)
        root.append(newEle)

    ImageID = filename.split(‘.‘)[0]
    # 创建elementtree对象,写入文件
    tree = ET.ElementTree(root)
    tree.write(savedir + ‘/‘+ ImageID + ".xml")
imagedir = r‘D:\test_dataset\labelimage‘
saveXMLdir = r‘D:\test_dataset\Annotations‘

if os.path.exists(saveXMLdir) is False:
    os.mkdir(saveXMLdir)

for root, _, fnames in sorted(os.walk(imagedir)):
    for fname in sorted(fnames):
        labelpath = os.path.join(root, fname)
        labelimage = misc.imread(labelpath)
        # 得到label图上的boundingingbox和数量
        objectnum, bbox = getboundingbox(labelimage)
        # label图 命名格式为 ImgeID_classname.png
        labelfilename = labelpath.split(‘\\‘)[-1]
        ImageID = labelfilename.split(‘.‘)[0].split(‘_‘)[0]
        classname = labelfilename.split(‘.‘)[0].split(‘_‘)[1]
        origin_image_name = ImageID +‘.jpg‘

        # 一些图片信息
        foldername = ‘test_dataset‘
        path  =‘\\‘.join(imagedir.split(‘\\‘)[:-1]) + ‘\\JPEGImage\\‘+ origin_image_name
        database = ‘Unknown‘
        width = str(labelimage.shape[0])
        height = str(labelimage.shape[1])
        depth = str(labelimage.shape[2])

        createXMLlabel(saveXMLdir,objectnum, bbox, classname, foldername=foldername,filename=origin_image_name, path=path,
                       database=database, width=width, height=height,depth=depth, segmented=‘0‘, pose="Unspecified",
                       truncated=‘0‘, difficult=‘0‘)

原文地址:https://www.cnblogs.com/smartweed/p/12153744.html

时间: 2024-07-29 19:38:13

分割数据集label转换为目标检测boundingbox的相关文章

VOC数据集 目标检测

最近在做与目标检测模型相关的工作,很多都要求VOC格式的数据集. PASCAL VOC挑战赛 (The PASCAL Visual Object Classes )是一个世界级的计算机视觉挑战赛, PASCAL全称:Pattern Analysis, Statical Modeling and Computational Learning,是一个由欧盟资助的网络组织.很多模型都基于此数据集推出.比如目标检测领域的yolo,ssd等等. voc数据集结构 看下目录结构 :~/git_project

AI佳作解读系列(五) - 目标检测二十年技术综述

计算机视觉中的目标检测,因其在真实世界的大量应用需求,比如自动驾驶.视频监控.机器人视觉等,而被研究学者广泛关注. 上周四,arXiv新出一篇目标检测文献<Object Detection in 20 Years: A Survey>,其对该领域20年来出现的技术进行了综述,这是一篇投向PAMI的论文,作者们review了400+篇论文,总结了目标检测发展的里程碑算法和state-of-the-art,并且难能可贵的对算法流程各个技术模块的演进也进行了说明,还深入到目标检测的特定领域,如人脸检

语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet,语义分割,简单来说就是给定一张图片,对图片中的每一个像素点进行分类;目标检测只有两类,目标和非目标,就是在一张图片中找到并用box标注出所有的目标.

from:https://blog.csdn.net/u012931582/article/details/70314859 2017年04月21日 14:54:10 阅读数:4369 前言 在这里,先介绍几个概念,也是图像处理当中的最常见任务. 语义分割(semantic segmentation) 目标检测(object detection) 目标识别(object recognition) 实例分割(instance segmentation) 语义分割 首先需要了解一下什么是语义分割(s

分类、目标检测、语义分割、实例分割的区别

计算机视觉的任务很多,有图像分类.目标检测.语义分割.实例分割和全景分割等,那它们的区别是什么呢? 1.Image Classification(图像分类) 图像分类(下图左)就是对图像判断出所属的分类,比如在学习分类中数据集有人(person).羊(sheep).狗(dog)和猫(cat)四种,图像分类要求给定一个图片输出图片里含有哪些分类,比如下图的例子是含有person.sheep和dog三种. 2.Object detection(目标检测) 目标检测(上图右)简单来说就是图片里面有什么

航空遥感图像(Aerial Images)目标检测数据集汇总

常规目标检测数据集有很多,现在前沿的目标检测算法(如Faster R-CNN, Yolo, SSD, Mask R-CNN等)基本都是在这些常规数据集上实验的,但是,基于常规数据集训练的分类器,在航空遥感图像上的检测效果并不好,主要原因是航空遥感图像有其特殊性: 1,尺度多样性,航空遥感图像从几百米到近万米的拍摄高度都有,且地面目标即使是同类目标也大小不一,如港口的轮船大的有300多米,小的也只有数十米: 2,视角特殊性,航空遥感图像的视角基本都是高空俯视,但常规数据集大部分还是地面水平视角,所

目标检测算法SSD在window环境下GPU配置训练自己的数据集

由于最近想试一下牛掰的目标检测算法SSD.于是乎,自己做了几千张数据(实际只有几百张,利用数据扩充算法比如镜像,噪声,切割,旋转等扩充到了几千张,其实还是很不够).于是在网上找了相关的介绍,自己处理数据转化为VOC数据集的格式,在转化为XML格式等等.具体方法可以参见以下几个博客.具体是window还是Linux请自行对号入座. Linux:http://blog.sina.com.cn/s/blog_4a1853330102x7yd.html window:http://blog.csdn.n

MaskLab-实例分割(使用语义分割和方向特征精细化目标检测)

MaskLab: Instance Segmentation by Refining Object Detection with Semantic and Direction Features 这是一篇2018年cvpr关于实例分割的网络模型,模型主要有三个输出:边界框.语义分割.方向预测. 整体框架 整个模型使用ResNet-101作为特征提取器,构建于Faster-RCNN之上.使用Faster-RCNN检测到目标框之后,使用相应的类别选取对应的语义通道并裁剪,接着结合方向预测再通过1x1的

基于Intel OpenVINO的搭建及应用,包含分类,目标检测,及分割,超分辨

PART I: 搭建环境OPENVINO+Tensorflow1.12.0 I: l_openvino_toolkit_p_2019.1.094 第一步常规安装参考链接:https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_linux.html 第二步编译Inference Engine Samples: cd /PATH/TO/deployment_tools/inference_eng

可以不用人工打标制作目标检测数据集的方法

1.我们将样品的背景采用不反光的布料类似下图 2.使用opencv中的阈值过滤方法 提取其中的灰度值在指定范围内的部分3.使用腐蚀处理 去除其中的干扰点4.提取图像中的轮廓点5.选取图中轮廓点的横纵最小最大坐标写入 voc数据集中的xml文件中即可输入深度学习网络进行实验 6.训练完目标检测网络之后识别效果如下图: 代码请参考 opencv_toturial一书 原文地址:http://blog.51cto.com/yixianwei/2096051