如何将yolo的标注(annotations).txt 坐标转换成tensorflow-yolov3(YunYang1994)的.txt 标注坐标?
生活随笔
收集整理的這篇文章主要介紹了
如何将yolo的标注(annotations).txt 坐标转换成tensorflow-yolov3(YunYang1994)的.txt 标注坐标?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 原理
- 示例
- 實現代碼
- 實際操作方法
原理
示例
如,這是Yolo的:
轉換后就變成醬紫了:
注意:圖像坐標原點在左上角
注意:作者引用圖片路徑時使用的時絕對路徑,我們使用相對路徑不知是否會出問題?
https://github.com/Dontla/tensorflow-yolov3/blob/master/data/dataset/voc_train.txt
文件批量重命名參考:python 將指定路徑(目錄)下的圖片或文本文件按給定序號重新排序,并批量重命名 yolo、tensorflow數據集批量處理
實現代碼
# -*- 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 = '../20191023_f_cotton_g/'source_txt_path = '../20191023_f_cotton_g_Annotations_Yolo/'target_txt_path = '../20191023_f_cotton_g_Annotations_Tensorflow-Yolov3_dataset/'# 讀取source_txt_path路徑下所有文件(包括子文件夾下文件)filenames = os.listdir(source_txt_path)# 調用自定義的sort_filenames函數對filenames重新排序(如果不重新排序它貌似會以1、10、100...的順序排而不是以1、2、3...的順序)pattern = '\((.*?)\)'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.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))))# 創建單行寫入字符串object_strs = source_img_path_related_to_train_py + os.path.splitext(filename)[0] + '.jpg'# print(os.path.splitext(filename))# ('f_cotton-g_top (1)', '.txt')# 將數據格式從相對坐標轉換成絕對坐標for object_str in content_extract:# print(object_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, object_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_height)(w, h) = (object_evar[3] * img_width, object_evar[4] * img_height)# 將映射變量格式化后加入到object_strs中:object_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()# 判斷該寫入哪個文件if (proba < train_scale):train_file_content += object_strs + '\n'else:test_file_content += object_strs + '\n'# 將兩個即將寫入的內容去除首位的無效字符(如空格,換行符,制表符,回車符)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('(.*?) ')'''實際操作方法
略
升級版:添加了數據清洗,參見:將yolo標注轉換為tensorflow_yolov3標注生成train.txt和test.txt同時做數據清洗
總結
以上是生活随笔為你收集整理的如何将yolo的标注(annotations).txt 坐标转换成tensorflow-yolov3(YunYang1994)的.txt 标注坐标?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python strip()方法 去除字
- 下一篇: win10如何将已有python环境变量