亲身体验后,告诫大家不要尝试这种整张图片全标记的方法,训练好后进行识别的结果简直惨不忍睹,因为有太多没有裂缝的部分也被全标记框柱,所以识别后整张图片中没有裂缝的部分也被识别为了裂缝。

在进行路面裂缝识别的项目中,我截取了9000多张只存在路面裂缝的100X100的图片,因为再进行一张一张的标注过于麻烦,所以我采用xml包利用python自动生成xml文件,作为yolov5识别的数据集。
数据集中xml文件的具体内容可以参考:PASCAL VOC 数据集简介

代码如下所示:

from lxml.etree import Element, SubElement, tostring
from xml.dom.minidom import parseString
import os


def make_xml(xmin_tuple, ymin_tuple, xmax_tuple, ymax_tuple, image_name):

    node_root = Element('annotation')

    node_folder = SubElement(node_root, 'folder')
    node_folder.text = 'images'

    node_filename = SubElement(node_root, 'filename')
    node_filename.text = image_name + '.jpg'

    # node_object_num = SubElement(node_root, 'object_num')
    # node_object_num.text = str(len(xmin_tuple))

    node_source = SubElement(node_root, 'source')
    node_database = SubElement(node_source, 'database')
    node_database.text = 'Unknown'

    node_size = SubElement(node_root, 'size')   # 图像尺寸, 用于对 bbox 左上和右下坐标点做归一化操作
    node_width = SubElement(node_size, 'width')
    node_width.text = '100'
    node_height = SubElement(node_size, 'height')
    node_height.text = '100'
    node_depth = SubElement(node_size, 'depth')
    node_depth.text = '3'

    node_segmented = SubElement(node_root, 'segmented')
    node_segmented.text = '0'

    for i in range(len(xmin_tuple)):
        node_object = SubElement(node_root, 'object')
        node_name = SubElement(node_object, 'name')   # 物体类别
        node_name.text = 'crack'
        node_pose = SubElement(node_object, 'pose')   # 拍摄角度:front, rear, left, right, unspecified
        node_pose.text = 'Unspecified'
        node_truncated = SubElement(node_object, 'truncated')   # 目标是否被截断(比如在图片之外),或者被遮挡(超过15%)
        node_truncated.text = '0'
        node_difficult = SubElement(node_object, 'difficult')   # 检测难易程度,这个主要是根据目标的大小,光照变化,图片质量来判断
        node_difficult.text = '0'

        node_bndbox = SubElement(node_object, 'bndbox')
        node_xmin = SubElement(node_bndbox, 'xmin')
        node_xmin.text = str(xmin_tuple[i])
        node_ymin = SubElement(node_bndbox, 'ymin')
        node_ymin.text = str(ymin_tuple[i])
        node_xmax = SubElement(node_bndbox, 'xmax')
        node_xmax.text = str(xmax_tuple[i])
        node_ymax = SubElement(node_bndbox, 'ymax')
        node_ymax.text = str(ymax_tuple[i])


    xml = tostring(node_root, pretty_print = True)
    dom = parseString(xml)
    return dom


# 读取所有文件名
def get_all_files(dir):
    files_ = []
    list = os.listdir(dir)
    for i in range(0, len(list)):
        path = os.path.join(dir, list[i])
        if os.path.isdir(path):
            files_.extend(get_all_files(path))
        if os.path.isfile(path):
            files_.append(path)
    return files_


if __name__ == '__main__':
    # dom = make_xml(xmin_tuple, ymin_tuple, xmax_tuple, ymax_tuple, image_name)
    # xml_name = os.path.join(save_xml_path, image_name + '.xml')

    image_name_list = get_all_files('data/images')
    print(image_name_list)
    for row in image_name_list:
        image_name = row.split('\\')[1].split('.')[0]

        dom = make_xml([0], [0], [100], [100], image_name)
        print(dom)
        xml_name = os.path.join('data/Annotations', image_name + '.xml')
        with open(xml_name, 'wb') as f:
            f.write(dom.toprettyxml(indent='\t', encoding='utf-8'))

生成的xml文件存放在data/Annotations文件夹内,某一xml文件结果为:

<?xml version="1.0" encoding="utf-8"?>
<annotation> 
	<folder>images</folder>
	<filename>1-3-1_0_200_100_300.jpg</filename>
	<source>
		<database>Unknown</database>
	</source>

	<size>
		<width>100</width>
		<height>100</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	
	<object>
		<name>crack</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		
		<bndbox>
			<xmin>0</xmin>
			<ymin>0</ymin>
			<xmax>100</xmax>
			<ymax>100</ymax>
		</bndbox>
	</object>
</annotation>
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐