文章目录

  • 代码:
  • 20200218 貌似上面代码有点bug,新的如下(解决了目标只有单行无法提取的bug,新增了将空目标图片汇总到文件夹的功能):

代码:

# -*- encoding: utf-8 -*-
"""
@File    : convert.py
@Time    : 2019/10/22 9:26
@Author  : Dontla
@Email   : sxana@qq.com
@Software: PyCharm
"""
import os
import re
import cv2
import random# 排序函数,对文件列表进行排序(filenames为文件夹文件的文件名的字符串列表,pattern为正则表达式,它是字符串类型)
def sort_filenames(filenames, pattern):# (1)可以以len排序,len相同的字符串,会再以0-9排序,能获得我们想要的结果# filenames.sort(key=len)# (2)这种排序失败了# filenames.sort(key=lambda x: x[16:])# print(filenames[0][16:])# 1).txt# (3)用lambda配合正则表达式(将filenames中对象一一取出赋给x,通过冒号后的表达式运算后将结果返回给key)# 数字字符串排序貌似还是以字符顺序而不是数字大小来排的,可能要先转化为数字(而re.findall('\((.*?)\)', x)返回的是字符串列表,要把它转换成数字列表)filenames.sort(key=lambda x: list(map(eval, re.findall(pattern, x))))# 注意括号前一定要添加转义字符“\”,不过有一个疑问,按照'((.*?))'排序为啥结果也正确??# print(filenames[0])# f_cotton-g_top (1).txt# print(re.findall('\((.*?)\)', filenames[0]))# ['1']# print(re.findall('((.*?))', filenames[0]))# [('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', '')]def extract_content(content):content_extract = re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)\n', content)return content_extractif __name__ == '__main__':# 记得路径尾部加“/”,不然调用join方法是它会用“\”替代,那样不好,容易造成转义字符问题。# ../表示上一层路径# 最终写入的文件路径信息是要给tensorflow-yolov3用的,我们要向其指定我们图片的位置:# source_img_path_related_to_train_py = '../Dontla_Dataset/20190822_Artificial_Flower/20191023_f_cotton_g/'source_img_path_related_to_train_py = './dontla_source_img/'# 以下三个路径是相对当前文件的source_img_path = './source_img_path/'source_txt_path = './source_txt_path/'target_txt_path = './target_txt_path/'# 读取source_txt_path路径下所有文件(包括子文件夹下文件)filenames = os.listdir(source_txt_path)# 调用自定义的sort_filenames函数对filenames重新排序(如果不重新排序它貌似会以1、10、100...的顺序排而不是以1、2、3...的顺序)# \是转义字符# pattern = '\((.*?)\)'# Dontla 20200204 现在文件名就是纯数字,所以pattern也得改pattern = '(.*?).txt'sort_filenames(filenames, pattern)# print(filenames)# ['f_cotton-g_top (1).txt', 'f_cotton-g_top (2).txt', 'f_cotton-g_top (3).txt',...]# 打开俩文件准备写入train_file = open(target_txt_path + 'train.txt', 'w', encoding='utf-8')test_file = open(target_txt_path + 'test.txt', 'w', encoding='utf-8')# 创建写入内容字符串变量train_file_content = ''test_file_content = ''# 打开文件提取其中数字并将内容重构后写入新文件for filename in filenames:# 打开文件:with open(os.path.join(source_txt_path, filename), 'r', encoding='utf-8') as f:# 读取文件内容content = f.read()# 提取数据content_extract = extract_content(content)# print(content_extract)# [('0', '0.228125', '0.670833', '0.164063', '0.227778'), ('0', '0.382031', '0.845139', '0.140625', '0.218056'),...]# 获取当前图片分辨率信息(这样不论图片尺寸多少都能成功转换)(re.findall()返回的是列表,需要将它转换成字符串)# 读取图片img = cv2.imread('{}{}.jpg'.format(source_img_path, ''.join(re.findall('(.*?).txt', filename))))# print(''.join(re.findall('(.*?).txt', filename)))# f_cotton-g_top (1)# 显示图片# cv2.namedWindow('test', cv2.WINDOW_AUTOSIZE)# cv2.imshow('test', img)# cv2.waitKey(0)# 获取图片分辨率img_width = img.shape[1]img_height = img.shape[0]# print(img.shape)# (720, 1280, 3)# f2.write('{}{}.jpg'.format(source_img_path_related_to_train_py, ''.join(re.findall('(.*?).txt', filename))))# 创建单行写入字符串的路径头字符串path_str = source_img_path_related_to_train_py + os.path.splitext(filename)[0] + '.jpg'# 创建单行写入字符串的目标坐标字符串obj_strs = ''# print(os.path.splitext(filename))# ('f_cotton-g_top (1)', '.txt')# 将数据格式从相对坐标转换成绝对坐标for obj_str in content_extract:# print(obj_str)# ('0', '0.228125', '0.670833', '0.164063', '0.227778')# ('0', '0.382031', '0.845139', '0.140625', '0.218056')# ('0', '0.380859', '0.652778', '0.135156', '0.200000')# ...# print(type(object_str))# <class 'tuple'># 将元组字符串转换成列表数字object_evar = list(map(eval, obj_str))# print(object_evar)# [0, 0.228125, 0.670833, 0.164063, 0.227778]# ...# 映射变量class_id = object_evar[0]x, y = object_evar[1] * img_width, object_evar[2] * img_heightw, h = object_evar[3] * img_width, object_evar[4] * img_height# 判断数据是否超出限制(数据清洗)(包括清洗超限坐标和错误class_id)if class_id != 0 \or round(x - w / 2) < 0 \or round(x + w / 2) > img_width \or round(x - w / 2) >= round(x + w / 2) \or round(y - h / 2) < 0 \or round(y + h / 2) > img_height \or round(y - h / 2) >= round(y + h / 2):print('错误标注:')print(filename)print(object_evar)print('[{}, {}, {}, {}, {}]'.format(round(x - w / 2), round(y - h / 2), round(x + w / 2),round(y + h / 2), class_id))continue# 将映射变量格式化后加入到obj_strs中:obj_strs += ' {},{},{},{},{}'.format(round(x - w / 2), round(y - h / 2), round(x + w / 2),round(y + h / 2), class_id)# 拆分训练集和测试集# 训练集占比train_scale = 0.75# 设置随机概率proba = random.random()# 如果该张图片经过数据清洗后没有目标,则跳过,不将其加入到train.txt和test.txt文件中if obj_strs == '':print('空文件')continueelse:write_strs = path_str + obj_strs# 判断该写入哪个文件if proba < train_scale:train_file_content += write_strs + '\n'else:test_file_content += write_strs + '\n'# print(write_strs)# ./dontla_source_img/1.jpg 275,138,374,226,0 669,36,782,153,0# ./dontla_source_img/2.jpg 453,228,623,366,0# ./dontla_source_img/3.jpg 723,269,847,414,0 339,376,541,494,0# ...# 将两个即将写入的内容去除首位的无效字符(如空格,换行符,制表符,回车符)train_file_content = train_file_content.strip()test_file_content = test_file_content.strip()# 将内容写入俩文件train_file.write(train_file_content)test_file.write(test_file_content)# 关闭俩文件train_file.close()test_file.close()

生成结果:

此代码是如何将yolo的标注(annotations).txt 坐标转换成tensorflow-yolov3(YunYang1994)的.txt 标注坐标?的升级版!!!

20200218 貌似上面代码有点bug,新的如下(解决了目标只有单行无法提取的bug,新增了将空目标图片汇总到文件夹的功能):

# -*- encoding: utf-8 -*-
"""
@File    : convert.py
@Time    : 2019/10/22 9:26
@Author  : Dontla
@Email   : sxana@qq.com
@Software: PyCharm
"""
import os
import re
import shutilimport cv2
import random# 排序函数,对文件列表进行排序(filenames为文件夹文件的文件名的字符串列表,pattern为正则表达式,它是字符串类型)
def sort_filenames(filenames, pattern):# (1)可以以len排序,len相同的字符串,会再以0-9排序,能获得我们想要的结果# filenames.sort(key=len)# (2)这种排序失败了# filenames.sort(key=lambda x: x[16:])# print(filenames[0][16:])# 1).txt# (3)用lambda配合正则表达式(将filenames中对象一一取出赋给x,通过冒号后的表达式运算后将结果返回给key)# 数字字符串排序貌似还是以字符顺序而不是数字大小来排的,可能要先转化为数字(而re.findall('\((.*?)\)', x)返回的是字符串列表,要把它转换成数字列表)filenames.sort(key=lambda x: list(map(eval, re.findall(pattern, x))))# 注意括号前一定要添加转义字符“\”,不过有一个疑问,按照'((.*?))'排序为啥结果也正确??# print(filenames[0])# f_cotton-g_top (1).txt# print(re.findall('\((.*?)\)', filenames[0]))# ['1']# print(re.findall('((.*?))', filenames[0]))# [('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', '')]def extract_content(content_):# 注意,一开始用的第一种,结果只有一行的情况没有被提取出来,要去掉后面的\n,谨记# content_extract = re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)\n', content)# content_extract = re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)', content)content_extract_ = re.findall('(\d+.?\d*) (\d+.?\d*) (\d+.?\d*) (\d+.?\d*) (\d+.?\d*)', content_)# print(content_extract_)return content_extract_# 20200216:直接从文件按行读取
def extract_content_readlines(content):content_extract = []for line in content:line = line.strip()# print('line:{}'.format(line))# line:0 0.248438 0.255556 0.128125 0.194444# line:0 0.571094 0.118056 0.118750 0.180556# line:0 0.457422 0.530556 0.113281 0.180556# ...# content_extract.append(re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)', line))content_extract.append(re.findall('(\d+.?\d*) (\d+.?\d*) (\d+.?\d*) (\d+.?\d*) (\d+.?\d*)', line))print(content_extract)return content_extractif __name__ == '__main__':# 记得路径尾部加“/”,不然调用join方法是它会用“\”替代,那样不好,容易造成转义字符问题。# ../表示上一层路径# 最终写入的文件路径信息是要给tensorflow-yolov3用的,我们要向其指定我们图片的位置:# source_img_path_related_to_train_py = '../Dontla_Dataset/20190822_Artificial_Flower/20191023_f_cotton_g/'source_img_path_related_to_train_py = './dontla_source_img/'# 以下三个路径是相对当前文件的source_img_path = './source_img_path/'source_txt_path = './source_txt_path/'target_txt_path = './target_txt_path/'# 读取source_txt_path路径下所有文件(包括子文件夹下文件)filenames = os.listdir(source_txt_path)# 调用自定义的sort_filenames函数对filenames重新排序(如果不重新排序它貌似会以1、10、100...的顺序排而不是以1、2、3...的顺序)# \是转义字符# pattern = '\((.*?)\)'# Dontla 20200204 现在文件名就是纯数字,所以pattern也得改pattern = '(.*?).txt'sort_filenames(filenames, pattern)# print(filenames)# ['f_cotton-g_top (1).txt', 'f_cotton-g_top (2).txt', 'f_cotton-g_top (3).txt',...]# TODO(Dontla): 提取filenames中数字'''for filename in filenames:if filename.endswith('.txt'):filepath = os.path.join(source_txt_path, filename)# print(filepath)'''# 获取所有txt文件的路径列表# 这么优雅的语法是从哪学来的?如实招来!# filepaths = [os.path.join(source_txt_path, filename) for filename in filenames if filename.endswith('.txt')]# 打开俩文件准备写入train_file = open(target_txt_path + 'train.txt', 'w', encoding='utf-8')test_file = open(target_txt_path + 'test.txt', 'w', encoding='utf-8')# 创建写入内容字符串变量train_file_content = ''test_file_content = ''# 打开文件提取其中数字并将内容重构后写入新文件for filename in filenames:# 打开文件:with open(os.path.join(source_txt_path, filename), 'r', encoding='utf-8') as f:# 读取文件内容(按行读取不是全部读取)# content = f.readlines()content = f.read()# 提取数据content_extract = extract_content(content)# 提取数据# content_extract = extract_content_readlines(content)# print(content_extract)# [('0', '0.228125', '0.670833', '0.164063', '0.227778'), ('0', '0.382031', '0.845139', '0.140625', '0.218056'),...]# 获取当前图片分辨率信息(这样不论图片尺寸多少都能成功转换)(re.findall()返回的是列表,需要将它转换成字符串)# 读取图片img = cv2.imread('{}{}.jpg'.format(source_img_path, ''.join(re.findall('(.*?).txt', filename))))# print(''.join(re.findall('(.*?).txt', filename)))# f_cotton-g_top (1)# 显示图片# cv2.namedWindow('test', cv2.WINDOW_AUTOSIZE)# cv2.imshow('test', img)# cv2.waitKey(0)# 获取图片分辨率img_width = img.shape[1]img_height = img.shape[0]# print(img.shape)# (720, 1280, 3)# f2.write('{}{}.jpg'.format(source_img_path_related_to_train_py, ''.join(re.findall('(.*?).txt', filename))))# 创建单行写入字符串的路径头字符串path_str = source_img_path_related_to_train_py + os.path.splitext(filename)[0] + '.jpg'# 创建单行写入字符串的目标坐标字符串obj_strs = ''# print(os.path.splitext(filename))# ('f_cotton-g_top (1)', '.txt')# 将数据格式从相对坐标转换成绝对坐标for obj_str in content_extract:# print(obj_str)# ('0', '0.228125', '0.670833', '0.164063', '0.227778')# ('0', '0.382031', '0.845139', '0.140625', '0.218056')# ('0', '0.380859', '0.652778', '0.135156', '0.200000')# ...# print(type(object_str))# <class 'tuple'># 将元组字符串转换成列表数字object_evar = list(map(eval, obj_str))# print(object_evar)# [0, 0.228125, 0.670833, 0.164063, 0.227778]# ...# 映射变量class_id = object_evar[0]x, y = object_evar[1] * img_width, object_evar[2] * img_heightw, h = object_evar[3] * img_width, object_evar[4] * img_height# 判断数据是否超出限制(数据清洗)(包括清洗超限坐标和错误class_id)if class_id != 0 \or round(x - w / 2) < 0 \or round(x + w / 2) > img_width \or round(x - w / 2) >= round(x + w / 2) \or round(y - h / 2) < 0 \or round(y + h / 2) > img_height \or round(y - h / 2) >= round(y + h / 2):print('错误标注:')print(filename)print(object_evar)print('[{}, {}, {}, {}, {}]'.format(round(x - w / 2), round(y - h / 2), round(x + w / 2),round(y + h / 2), class_id))continue# 将映射变量格式化后加入到obj_strs中:obj_strs += ' {},{},{},{},{}'.format(round(x - w / 2), round(y - h / 2), round(x + w / 2),round(y + h / 2), class_id)# 拆分训练集和测试集# 训练集占比train_scale = 0.75# 设置随机概率proba = random.random()# 如果该张图片经过数据清洗后没有目标,则跳过,不将其加入到train.txt和test.txt文件中if obj_strs == '':print('空文件:{}'.format(filename))print('content:{}'.format(content))# print('content_extract:{}'.format(content_extract))# print(re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)\n', content))cv2.imwrite('null_img\\{}.jpg'.format(''.join(re.findall('(.*?).txt', filename))), img)print('将图片拷贝到“空文件”文件夹')continueelse:write_strs = path_str + obj_strsprint(write_strs)# 判断该写入哪个文件if proba < train_scale:train_file_content += write_strs + '\n'else:test_file_content += write_strs + '\n'# print(write_strs)# ./dontla_source_img/1.jpg 275,138,374,226,0 669,36,782,153,0# ./dontla_source_img/2.jpg 453,228,623,366,0# ./dontla_source_img/3.jpg 723,269,847,414,0 339,376,541,494,0# ...# 将两个即将写入的内容去除首位的无效字符(如空格,换行符,制表符,回车符)train_file_content = train_file_content.strip()test_file_content = test_file_content.strip()# 将内容写入俩文件train_file.write(train_file_content)test_file.write(test_file_content)# 关闭俩文件train_file.close()test_file.close()'''all = os.walk(source_txt_path)# dirpath:从all中存储的source_txt_path下文件夹及子文件夹列表中取出每个文件夹及子文件夹路径# dirnames :dirpath下的文件夹列表(不包括子文件夹)# filenames :dirpath下文件的文件名列表for dirpath, dirnames, filenames in all:# print('path:',dirpath)# print('dir:',dirnames)# print('filelist:',filenames)for filename in filenames:# print(filename)# 20190822_Artificial_Flower (1).txtif filename.endswith('.txt'):filepath = os.path.join(dirpath, filename)# print(filepath)# ../20190822_Artificial_Flower_Annotations_Yolo/20190822_Artificial_Flower (99).txtwith open(filepath, 'r', encoding='utf-8') as f:content=f.read()# 不能省略\n不然就识别不出来了# content_extract=re.findall('(.*) (.*) (.*) (.*) (.*)\n',content)content_extract=re.findall('(.*?) (.*?) (.*?) (.*?) (.*?)\n',content)# print(content_extract)# [('0', '0.491797', '0.772917', '0.103906', '0.170833'), ('0', '0.355078', '0.569444', '0.116406', '0.183333')]# Dontla deleted 20191023# with open(filepath,'r',encoding='utf-8') as f:#     content_list=f.readlines()##     # print(content_list)#     # ['0 0.491797 0.772917 0.103906 0.170833\n', '0 0.355078 0.569444 0.116406 0.183333\n']##     for content in content_list:#         break#     # target_info=re.findall('(.*?) ')'''

参考文章:yuyang1994 tensorflow_yolov3训练报错:IndexError: index 68 is out of bounds for axis 1 with size 68(数据清洗)

将yolo标注转换为tensorflow_yolov3标注生成train.txt和test.txt同时做数据清洗相关推荐

  1. 深度学习数据标注_Lableme及标注文件的使用(以YOLO v3为例)

    图像标注工具Lable labelme 是一款图像标注工具,主要用于神经网络构建前的数据集准备工作,因为是用 Python 写的,所以使用前需要先安装 Python 集成环境 anaconda. an ...

  2. VOC/YOLO/COCO数据集格式转换及LabelImg/Labelme/精灵标注助手Colabeler标注工具介绍

    数据集格式:VOC(xml).YOLO(txt).COCO(json) 本文主要对Label格式,以及LabelImg.Labelme.精灵标注助手Colabeler这常用的三种数据标注软件进行介绍. ...

  3. 将widerface标注转换为VOC格式

    验证工具代码: https://github.com/wondervictor/WiderFace-Evaluation 将widerface标注转换为VOC格式 原文:https://blog.cs ...

  4. 关于在Win10系统将标注软件labelme打包生成.exe可执行文件

    由于在学习语义分割框架,安装好相关环境后,下一步就是准备数据集进行训练了,网上也找了一些数据集,但还没有开始训练.因为语义分割的数据集和目标检测有一些区别,加之以前自己制作目标检测数据集都是在已有基础 ...

  5. 摹客标注:自动标注一键生成,手动标注自由补充

    熬着夜手动做标注? 用工具自动标注,却被攻城狮追命连环call? 设计稿标注--其实--可以「自动+手动」! 摹客,「自动标注」一键生成,「手动标注」自由补充, 助你五星通过标注大关~ 「自动+手动」 ...

  6. lisp 标记形心_DXF组码来生成标注样式(标注文字样式、标注箭头样式)

    本文介绍AutoLisp用DXF组码来生成标注样式(标注文字样式.标注箭头样式)方法. 一.先生成标注文本样式(若已存在则忽略此步) 说明:用DXF组码生成标注样式中的标注文字样式时,其DXF参考中组 ...

  7. Auto Lisp 标注子样式_DXF组码来生成标注样式(标注文字样式、标注箭头样式)...

    本文介绍AutoLisp用DXF组码来生成标注样式(标注文字样式.标注箭头样式)方法. 一.先生成标注文本样式(若已存在则忽略此步) 说明:用DXF组码生成标注样式中的标注文字样式时,其DXF参考中组 ...

  8. mnist转换为3通道的224*244,生成训练train.txt和vaild.txt

    参考GitHub: https://github.com/yangninghua/deeplearning_backbone 生成txt import numpy as np import struc ...

  9. 什么是数据标注? 数据标注公司主要做什么?

    一.什么是数据标注? 1.数据标注定义 数据标注是对未经处理的语音.图片.文本.视频等数据进行加工处理, 并转换为机器可识别信息的过程.原始数据一般通过数据采集获得, 随后的数据标注相当于对数据进行加 ...

最新文章

  1. linux 卸载 openssl,请教Linux下Openssl安装的问题。
  2. python 效率_Python 运行效率为何低
  3. 更改python默认路径_Linux下多版本python共存时,默认执行路径修改方法
  4. window php 安装zip扩展,Windows下安装php_rar 扩展,让php实现rar文件的读取和解压
  5. python保存不了_新手,我的python保存不了文件
  6. 【CCCC】L2-003 月饼 (25分),贪心
  7. 802.11的CSMA/CA机制
  8. iOS 人民币符号与日圆符号的混淆
  9. 扩展PHP内置的异常处理类
  10. 房间WIFI信号不好怎么办?——无线路由桥接(WDS)
  11. 计算机解八元一次方程,如何用matlab求解8元一次,含参数的方程组(共八个一次方程)...
  12. 【优动漫 PAINT应用篇】绘制插画之草稿
  13. 计算机网络 网络层 私网地址和公网地址及子网划分
  14. 【Jsoup】 基本使用
  15. SDN:简述对各类SDN交换机的认识
  16. 如何查看本机的ip地址和端口号
  17. ubuntu16.04安装xmind8
  18. 数字内容产业的政策背景与发展现状
  19. 模拟HTTP请求, POST方法(附源码)
  20. HTML5 postMessage 和 onmessage API 详细应用

热门文章

  1. asp.net获取客户端信息
  2. 【学习笔记】Python - Beautiful Soup
  3. 可以扣6分也可以扣0分?闯红灯也是有技巧的
  4. SAP系统安装技术要求
  5. SAP HANA简介
  6. FM之RKD_WORD_WRAP
  7. 备受诟病的导购,不过是在替屈臣氏挡子弹
  8. “腾讯电竞”向前,“腾讯游戏”向后
  9. 计算机在线考试系统的参考文献,基于JSP的在线考试系统
  10. python解压文件_Python压缩和解压缩文件(zip/unzip)详解