• 数据集的整理和命名和格式转换


    e智团队实验室项目-数据集的整理和命名和格式转换

    赵雅玲 *, 张钊* ,赵尉* 

    (淮北师范大学计算机科学与技术学院,淮北师范大学经济与管理学院,安徽 淮北)

    *These authors contributed to the work equllly and should be regarded as co-first authors.

    🌞欢迎来到深度学习的世界 
    🌈博客主页:卿云阁

    💌欢迎关注🎉点赞👍收藏⭐️留言📝

    🌟本文由卿云阁原创!

    🌠本阶段属于练气阶段,希望各位仙友顺利完成突破

    📆首发时间:🌹2022年11月10日🌹

    ✉️希望可以和大家一起完成进阶之路!

    🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


    目录

    🍈 数据集的划分

     🍉命名

    🍻格式的转换

    🍈 数据集的划分

          对机器学习和深度学习而言,都需要进行训练集和测试集的划分,在运行一些目标检测算法的时候,经常需要手写代码进行划分,这里为大家整理好了一份代码。

    1. # 将图片和标注数据按比例切分为 训练集和测试集
    2. import shutil
    3. import random
    4. import os
    5. # 原始路径
    6. image_original_path = 'D:\sraffic_news\images/'
    7. label_original_path = 'D:\sraffic_news\labels/'
    8. # 训练集路径
    9. train_image_path = 'D:\sraffic_news\ train\images/'
    10. train_label_path = 'D:\sraffic_news\ train\labels/'
    11. # 验证集路径
    12. val_image_path = 'D:\sraffic_news\ val\images/'
    13. val_label_path = 'D:\sraffic_news\ val\labels/'
    14. # 测试集路径
    15. test_image_path = 'D:\sraffic_news\ test\images/'
    16. test_label_path = 'D:\sraffic_news\ test\labels/'
    17. # 数据集划分比例,训练集75%,验证集15%,测试集15%
    18. train_percent = 0.8
    19. val_percent = 0.1
    20. test_percent = 0.1
    21. # 检查文件夹是否存在
    22. def mkdir():
    23. if not os.path.exists(train_image_path):
    24. os.makedirs(train_image_path)
    25. if not os.path.exists(train_label_path):
    26. os.makedirs(train_label_path)
    27. if not os.path.exists(val_image_path):
    28. os.makedirs(val_image_path)
    29. if not os.path.exists(val_label_path):
    30. os.makedirs(val_label_path)
    31. if not os.path.exists(test_image_path):
    32. os.makedirs(test_image_path)
    33. if not os.path.exists(test_label_path):
    34. os.makedirs(test_label_path)
    35. def main():
    36. mkdir()
    37. total_txt = os.listdir(label_original_path)
    38. num_txt = len(total_txt)
    39. list_all_txt = range(num_txt) # 范围 range(0, num)
    40. num_train = int(num_txt * train_percent)
    41. num_val = int(num_txt * val_percent)
    42. num_test = num_txt - num_train - num_val
    43. train = random.sample(list_all_txt, num_train)
    44. # train从list_all_txt取出num_train个元素
    45. # 所以list_all_txt列表只剩下了这些元素:val_test
    46. val_test = [i for i in list_all_txt if not i in train]
    47. # 再从val_test取出num_val个元素,val_test剩下的元素就是test
    48. val = random.sample(val_test, num_val)
    49. # 检查两个列表元素是否有重合的元素
    50. # set_c = set(val_test) & set(val)
    51. # list_c = list(set_c)
    52. # print(list_c)
    53. # print(len(list_c))
    54. print("训练集数目:{}, 验证集数目:{},测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))
    55. for i in list_all_txt:
    56. name = total_txt[i][:-4]
    57. srcImage = image_original_path + name + '.jpg'
    58. srcLabel = label_original_path + name + '.txt'
    59. if i in train:
    60. dst_train_Image = train_image_path + name + '.jpg'
    61. dst_train_Label = train_label_path + name + '.txt'
    62. shutil.copyfile(srcImage, dst_train_Image)
    63. shutil.copyfile(srcLabel, dst_train_Label)
    64. elif i in val:
    65. dst_val_Image = val_image_path + name + '.jpg'
    66. dst_val_Label = val_label_path + name + '.txt'
    67. shutil.copyfile(srcImage, dst_val_Image)
    68. shutil.copyfile(srcLabel, dst_val_Label)
    69. else:
    70. dst_test_Image = test_image_path + name + '.jpg'
    71. dst_test_Label = test_label_path + name + '.txt'
    72. shutil.copyfile(srcImage, dst_test_Image)
    73. shutil.copyfile(srcLabel, dst_test_Label)
    74. if __name__ == '__main__':
    75. main()

     🍉命名

          首先,大家第一时间想到的肯定是在文件夹中Ctrl+A全选,接着,右键选择重命名,或者是下载一个图片处理工具,但是前者却会出现下图的问题,命名后会出现烦人的“()”,不符合要求;而后者,先不说下载耽误时间,如果对于处理大量图片命名的工程是极其慢的(本人曾尝试过),因为当你下载好软件后,你要将所有图片一一上传至该软件,之后再一张一张的命名和保存(该过程是无法操作的,只能苦苦等待),整个过程下来已经超过了截止时间了。接下来我来介绍一种可以超快速给大量图片批量名的方法,请小伙伴们认真学习。

    操作步骤:

    打开文件夹,点击右上角箭头,接着Ctrl+A全选图片,

    点击左上角的“复制路径”(就是复制了所有图片的地址),打开Excel表格,将其粘贴到表格中;

    之后手动提取图片的后缀名称“绿灯(1).jpg”到第二列,然后按下Ctrl+E批量提取;

    然后再第三列输入你想要替换的图片名;

    接下来将代码(="ren """&B2&""" "&C2)输入到第四列后,按回车,双击右下角填充代码,如下图,代码中的B2、C2分别是被替换名和替换名,可以根据需要随意调整,其中“ren”是rename的简写,

    该代码的公式为:ren+空格+旧图片名+空格+新文件名;

     

    然后复制所有的代码,在图片文件夹中新建一个txt文档,把代码粘贴进去,保存文本文档;

    将编码改为ANSl,再将文件名后缀改为“.BAT”,然后保存后,运行生成的.BAT文件,然后图片的批量修改就完成了!


    🍻格式的转换

        对于目标检测算法,一共有两种形式的标签。一种是txt格式,一种是xml格式。

    txt与xml格式的转换

    1. from xml.dom.minidom import Document
    2. import os
    3. import cv2
    4. # def makexml(txtPath, xmlPath, picPath): # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
    5. def makexml(picPath, txtPath, xmlPath): # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
    6. """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
    7. 在自己的标注图片文件夹下建三个子文件夹,分别命名为picture、txt、xml
    8. """
    9. dic = {'0': "green", # 创建字典用来对类型进行转换
    10. '1': "red", # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
    11. }
    12. files = os.listdir(txtPath)
    13. for i, name in enumerate(files):
    14. xmlBuilder = Document()
    15. annotation = xmlBuilder.createElement("annotation") # 创建annotation标签
    16. xmlBuilder.appendChild(annotation)
    17. txtFile = open(txtPath + name)
    18. txtList = txtFile.readlines()
    19. img = cv2.imread(picPath + name[0:-4] + ".jpg")
    20. Pheight, Pwidth, Pdepth = img.shape
    21. folder = xmlBuilder.createElement("folder") # folder标签
    22. foldercontent = xmlBuilder.createTextNode("driving_annotation_dataset")
    23. folder.appendChild(foldercontent)
    24. annotation.appendChild(folder) # folder标签结束
    25. filename = xmlBuilder.createElement("filename") # filename标签
    26. filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
    27. filename.appendChild(filenamecontent)
    28. annotation.appendChild(filename) # filename标签结束
    29. size = xmlBuilder.createElement("size") # size标签
    30. width = xmlBuilder.createElement("width") # size子标签width
    31. widthcontent = xmlBuilder.createTextNode(str(Pwidth))
    32. width.appendChild(widthcontent)
    33. size.appendChild(width) # size子标签width结束
    34. height = xmlBuilder.createElement("height") # size子标签height
    35. heightcontent = xmlBuilder.createTextNode(str(Pheight))
    36. height.appendChild(heightcontent)
    37. size.appendChild(height) # size子标签height结束
    38. depth = xmlBuilder.createElement("depth") # size子标签depth
    39. depthcontent = xmlBuilder.createTextNode(str(Pdepth))
    40. depth.appendChild(depthcontent)
    41. size.appendChild(depth) # size子标签depth结束
    42. annotation.appendChild(size) # size标签结束
    43. for j in txtList:
    44. oneline = j.strip().split(" ")
    45. object = xmlBuilder.createElement("object") # object 标签
    46. picname = xmlBuilder.createElement("name") # name标签
    47. namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
    48. picname.appendChild(namecontent)
    49. object.appendChild(picname) # name标签结束
    50. pose = xmlBuilder.createElement("pose") # pose标签
    51. posecontent = xmlBuilder.createTextNode("Unspecified")
    52. pose.appendChild(posecontent)
    53. object.appendChild(pose) # pose标签结束
    54. truncated = xmlBuilder.createElement("truncated") # truncated标签
    55. truncatedContent = xmlBuilder.createTextNode("0")
    56. truncated.appendChild(truncatedContent)
    57. object.appendChild(truncated) # truncated标签结束
    58. difficult = xmlBuilder.createElement("difficult") # difficult标签
    59. difficultcontent = xmlBuilder.createTextNode("0")
    60. difficult.appendChild(difficultcontent)
    61. object.appendChild(difficult) # difficult标签结束
    62. bndbox = xmlBuilder.createElement("bndbox") # bndbox标签
    63. xmin = xmlBuilder.createElement("xmin") # xmin标签
    64. mathData = int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)
    65. xminContent = xmlBuilder.createTextNode(str(mathData))
    66. xmin.appendChild(xminContent)
    67. bndbox.appendChild(xmin) # xmin标签结束
    68. ymin = xmlBuilder.createElement("ymin") # ymin标签
    69. mathData = int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)
    70. yminContent = xmlBuilder.createTextNode(str(mathData))
    71. ymin.appendChild(yminContent)
    72. bndbox.appendChild(ymin) # ymin标签结束
    73. xmax = xmlBuilder.createElement("xmax") # xmax标签
    74. mathData = int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)
    75. xmaxContent = xmlBuilder.createTextNode(str(mathData))
    76. xmax.appendChild(xmaxContent)
    77. bndbox.appendChild(xmax) # xmax标签结束
    78. ymax = xmlBuilder.createElement("ymax") # ymax标签
    79. mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
    80. ymaxContent = xmlBuilder.createTextNode(str(mathData))
    81. ymax.appendChild(ymaxContent)
    82. bndbox.appendChild(ymax) # ymax标签结束
    83. object.appendChild(bndbox) # bndbox标签结束
    84. annotation.appendChild(object) # object标签结束
    85. f = open(xmlPath + name[0:-4] + ".xml", 'w')
    86. xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
    87. f.close()
    88. if __name__ == "__main__":
    89. picPath = "D:\VOCdevkit/VOC2007/JPEGImages/" # 图片所在文件夹路径,后面的/一定要带上
    90. txtPath = "D:\VOCdevkit/VOC2007/YOLO/" # txt所在文件夹路径,后面的/一定要带上
    91. xmlPath = "D:\VOCdevkit/VOC2007/Annotations/" # xml文件保存路径,后面的/一定要带上
    92. makexml(picPath, txtPath, xmlPath)

    xml与txt格式的转换

    1. import xml.etree.ElementTree as ET
    2. import pickle
    3. import os
    4. from os import listdir, getcwd
    5. from os.path import join
    6. import glob
    7. classes = ["green", "red"]
    8. def convert(size, box):
    9. dw = 1.0 / size[0]
    10. dh = 1.0 / size[1]
    11. x = (box[0] + box[1]) / 2.0
    12. y = (box[2] + box[3]) / 2.0
    13. w = box[1] - box[0]
    14. h = box[3] - box[2]
    15. x = x * dw
    16. w = w * dw
    17. y = y * dh
    18. h = h * dh
    19. return (x, y, w, h)
    20. def convert_annotation(image_name):
    21. in_file = open('./datasets/Annotations/outputs/' + image_name[:-3] + 'xml') # xml文件路径
    22. out_file = open('./datasets/ImageSets/' + image_name[:-3] + 'txt', 'w') # 转换后的txt文件存放路径
    23. f = open('./datasets/Annotations/outputs/' + image_name[:-3] + 'xml')
    24. xml_text = f.read()
    25. root = ET.fromstring(xml_text)
    26. f.close()
    27. size = root.find('size')
    28. w = int(size.find('width').text)
    29. h = int(size.find('height').text)
    30. for obj in root.iter('object'):
    31. cls = obj.find('name').text
    32. if cls not in classes:
    33. print(cls)
    34. continue
    35. cls_id = classes.index(cls)
    36. xmlbox = obj.find('bndbox')
    37. b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
    38. float(xmlbox.find('ymax').text))
    39. bb = convert((w, h), b)
    40. out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
    41. wd = getcwd()
    42. if __name__ == '__main__':
    43. for image_path in glob.glob("./datasets/images/*.jpg"): # 每一张图片都对应一个xml文件这里写xml对应的图片的路径
    44. image_name = image_path.split('\\')[-1]
    45. convert_annotation(image_name)

    Institutional Review Board Statement: Not applicable.

    Informed Consent Statement: Not applicable.

    Data Availability Statement: Not applicable.

    Author Contributions:All authors participated in the assisting performance study and approved the paper.

    Conflicts of Interest: The authors declare no conflict of interes

  • 相关阅读:
    Go语言sync.Map
    3.蓝牙模块HC-08
    【SpringBoot实践】事务和事务传播机制&失效原因&正确使用事务的建议
    串口服务器和光纤交换机的区别
    CSDN 云IDE初体验 - 不负所望
    Codeforces Round #832 (Div. 2)
    世界启动Ⅰ--6个让你惊叹的开源项目
    华为MTL流程的六个模块初步解析
    科技改变视听4K 120HZ高刷新率的投影、电视、电影终有用武之地
    R语言ggplot2可视化分面折线图:使用facet_wrap函数可视化分面折线图、color参数和size参数自定义线条的颜色和宽度粗细
  • 原文地址:https://blog.csdn.net/zzqingyun/article/details/127797303