Dividing the data set into target detection label boundingbox

Realize the function

FIG label is divided into target detection boundingbox label file (VOC format).

Note:

1. split the sample in a picture only in the same category multiple targets.

2. The conversion is achieved by communicating to boundingbox label field, you can not overlap the target process, as a monogram .

Dataset format

Wherein the divided semantic data set in the following format:

In the original picture JPEGImages folder naming format is ImageID.jpg

    

Label chart labelimage folder naming format is ImageID_classname.png

     

Boundingbox generated names of the form marked ImageID.xml

   

XML tagging format

<annotation>
   <folder>road_dataset</folder>                      #文件名
   <Filename> 3425.jpg </ filename> # the name of the original picture
   <Path> D: \ road_dataset \ JPEGImages \ 3425.jpg </ path> # original picture address
   <source>
      <database>Unknown</database>
   </source>
   <Size> # image size
      <width>512</width>
      <height>512</height>
      <depth>3</depth>
   </size>
   <Segmented> 0 </ segmented> # is for dividing, 0 NO
   <Object> # target
      <Name> butt </ name> # category name
      <Pose> Unspecified </ pose> # photographing angle
      <Truncated> 0 </ truncated> # whether truncated
      <Difficult> 0 </ difficult> # whether it is difficult samples
      <Bndbox> #boundingbox coordinates (bottom left, top right)
         <xmin>327</xmin>
         <ymin>38</ymin>
         <xmax>394</xmax>
         <ymax>69</ymax>
      </bndbox>
   </object>
   <Object> # multiple targets
      <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>

Wherein <pose> <truncated> <difficult> all default values.

FIG communication domain to obtain the label

Skimage use of morphology, measure the number and give the object boundingbox on each sub-picture through the communication field.

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

# Because the goal of a picture, only one category, so the label map mark only black and white 
rgbmask = np.array ([[0,0,0], [255,255,255]], dtype = np.uint8)

# Obtained from the label and FIGS number boundingbox communication domains on FIG 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
     # Deletion of less than 10 pixels of the target 
    mask_without_small = morphology.remove_small_objects (mask, min_size = 10 , Connectivity = 2 )
     # connected component labeling 
    label_image = measure.label (mask_without_small)
     # count the number Object 
    Object_Num = len (measure.regionprops (label_image))
    BoundingBox = List ()
     for Region in measure.regionprops (label_image):   # circulating the communication field each BBOX 
        boundingbox.append (region.bbox)
     return Object_Num, BoundingBox

Boundingbox picture displayed on the label, see the results:

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

# Output as the image to see the effect obtained boundingbox 
IMAGEDIR R & lt = ' 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')

The output image is:

Generate XML annotation file

createXMLlabel: generate an XML file labeled according to label information
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')

 

Guess you like

Origin www.cnblogs.com/smartweed/p/12153744.html
Recommended