网站 | 备注 |
---|---|
github项目官网 | 源码下载 |
官方说明文档 | 教程配置 |
roboflow社区 | 找数据集 |
roboflow项目 | 制作工具 |
yolov8训练教程 | 参考链接 |
from ultralytics import YOLO
if __name__ == '__main__':
mode = 'predict' # train validate predict export track
if mode == 'train':
# 模型训练
model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/weight/yolov8s.pt')
results = model.train(epochs=100,
patience=100,
batch=42,
save_period=20,
imgsz=640,
multi_scale=False,
cache=False,
device=[0,1],
project='head_train',
name='exp',
)
if mode == 'validate':
# 模型测试
model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/head_train/exp/weights/best.pt')
# Validate the model
metrics = model.val(source='/home/ws/CoodWorkRun/yolov8/ultralyticsv8/test_data/cx2',
conf=0.2,
iou=0.7,
max_det=1000,
save_json=False,
save_hybrid=False,
)
if mode == 'predict':
# 模型推理
# model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/head_train/exp/weights/best.pt')
model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/head_train/exp/weights/best.pt')
results = model.predict(source='/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/test_data/cx2',
conf=0.2,
iou=0.1,
max_det=1000,
imgsz=640,
save=True,
augment=True,
save_txt=True,
save_crop= True,
show_labels=True,
show_conf=True,
show_boxes=True,
)
# 预测框数据处理
for result in results:
boxes = result.boxes # Boxes object for bbox outputs
masks = result.masks # Masks object for segmentation masks outputs
keypoints = result.keypoints # Keypoints object for pose outputs
probs = result.probs # Probs object for classification outputs
if mode == 'export':
# 模型导出
model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/head_train/exp/weights/best.pt')
# Export the model
model.export(format='onnx', #engine onnx
imgsz=640,
workspace=4,
)
if mode == 'track':
# 跟踪任务
model = YOLO('/home/ws/CoodWorkRun/yolov8/ultralyticsv8/cood/head_train/exp/weights/best.pt')
results = model.track(source="/home/ws/CoodWorkRun/yolov8/ultralyticsv8/test_data/cx1",
conf=0.2,
iou=0.5,
save=True,
show=True)
# 视频裁图片
import cv2
import os
from tqdm import tqdm
# 视频文件夹路径和保存图片的文件夹路径
video_folder = '/home/ws/CoodWorkRun/yolov5_cr/tool/newph/video'
photo_folder = '/home/ws/CoodWorkRun/yolov5_cr/tool/newph/photo'
exp_folder = os.path.join(photo_folder, 'exp')
# 创建保存图片的文件夹(如果不存在)
if not os.path.exists(exp_folder):
os.makedirs(exp_folder)
# 获取视频文件夹中的所有视频文件
video_files = [f for f in os.listdir(video_folder) if f.endswith('.mp4')]
# 遍历每个视频文件
for video_file in video_files:
# 构建视频文件的完整路径
video_path = os.path.join(video_folder, video_file)
# 使用OpenCV读取视频
cap = cv2.VideoCapture(video_path)
# 检查视频是否成功打开
if not cap.isOpened():
print(f"无法打开视频文件:{video_file}")
continue
# 获取视频的帧率
fps = cap.get(cv2.CAP_PROP_FPS)
# 初始化帧计数器
frame_count = 0
# 初始化图片计数器
photo_count = 0
# 遍历视频的每一帧,添加tqdm进度条
for _ in tqdm(range(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))):
# 读取一帧图片
ret, frame = cap.read()
# 检查是否成功读取帧
if not ret:
break
# CarHead
# 仅处理每隔10帧的情况
if frame_count % 20 == 0:
# 构建保存图片的文件名
photo_file = f"AsHead_{video_file}_{photo_count}.jpg"
photo_path = os.path.join(exp_folder, photo_file)
# 保存图片
cv2.imwrite(photo_path, frame)
# 增加图片计数器
photo_count += 1
# 增加帧计数器
frame_count += 1
# 释放视频对象
cap.release()
# 输出图片数量
print(f"视频{video_file}截取了{photo_count}张图片")
# A文件夹 复制到 B文件夹
import shutil
import os
# 设置原始文件夹路径和目标文件夹路径
source_folder = r'/home/ws/CoodWorkRun/Database/12w/HeadDB/label'
target_folder = r'/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB_faceDB_v2/label'
# 判断目标文件夹是否存在,如果不存在则创建
if not os.path.exists(target_folder):
os.makedirs(target_folder)
# 遍历源文件夹中的所有文件,将文件复制到目标文件夹中
for filename in os.listdir(source_folder):
source_path = os.path.join(source_folder, filename)
target_path = os.path.join(target_folder, filename)
shutil.copyfile(source_path, target_path)
import os
# 标注统计
# 指定要统计的文件夹路径
train_folder_path = '/home/ws/CoodWorkRun/Database/DatabaseDTall/train/labels'
val_folder_path = '/home/ws/CoodWorkRun/Database/DatabaseDTall/val/labels'
# 初始化数字行数统计列表
count_list = [0] * 9
# 定义函数用于统计指定文件夹中的txt文件
def count_lines(folder_path):
# 遍历文件夹中的所有txt文件
for filename in os.listdir(folder_path):
if filename.endswith(".txt"):
file_path = os.path.join(folder_path, filename)
with open(file_path, 'r') as file:
# 逐行读取文件内容并统计以0到8开头的行数
for line in file:
first_char = line.strip()[0]
if first_char.isdigit() and int(first_char) in range(9):
count_list[int(first_char)] += 1
# # 统计训练集文件夹中的txt文件
# count_lines(train_folder_path)
# 统计验证集文件夹中的txt文件
count_lines(val_folder_path)
# 输出统计结果
for digit, count in enumerate(count_list):
print(f"数字 {digit} 开头的行数为: {count}")
# 改标签文件对应数字
import os
folder_path = r'/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB_faceDB_v2/HeadDB/label'
# 遍历文件夹中的每个txt文件
for filename in os.listdir(folder_path):
if filename.endswith('.txt'):
file_path = os.path.join(folder_path, filename)
# 读取txt文件内容
with open(file_path, 'r') as file:
lines = file.readlines()
# 修改每一行的第一个数字为2
modified_lines = []
for line in lines:
split_line = line.strip().split(' ')
split_line[0] = '3'
modified_line = ' '.join(split_line) + '\n'
modified_lines.append(modified_line)
# 将修改后的内容写入文件
with open(file_path, 'w') as file:
file.writelines(modified_lines)
print("修改完成!")
# 提取对应类别数据集
#
from pycocotools.coco import COCO
import os
import shutil
from tqdm import tqdm
import skimage.io as io
import matplotlib.pyplot as plt
import cv2
from PIL import Image, ImageDraw
# 参考链接
# https://blog.csdn.net/Accelerating/article/details/126855883
# https://blog.csdn.net/Dongjiuqing/article/details/127949190
pathset = 'wine glass'
'''
交通 'person', 'bicycle', 'car', 'motorcycle', 'bus', 'train', 'truck'
'人', ' 自行车', '汽车', '摩托车', '公共汽车', '火车', '卡车'
257249 7056 43532 8654 6061 4570 9970
物品 'bottle', 'wine glass', 'cup', 'bowl', 'fork', 'knife', 'spoon',
'瓶子', '酒杯', '杯子', '碗', '叉子', '刀', '勺子',
24070 7839 20574 14323
手机 'cell phone'
'''
# 需要设置的路径
savepath = r"C:/Users/User/Desktop/coco/transfer/"+pathset+'/'
# print(savepath)
img_dir = savepath + 'images/'
anno_dir = savepath + 'annotations/'
datasets_list = ['train2017', 'val2017']
# datasets_list = ['val2017']
# coco有80类,这里写要提取类的名字,以person为例
classes_names = [pathset]
# 包含所有类别的原coco数据集路径
'''
目录格式如下:
$COCO_PATH
----|annotations
----|train2017
----|val2017
----|test2017
'''
dataDir = 'C:/Users/User/Desktop/coco/'
headstr = """\
<annotation>
<folder>VOC</folder>
<filename>%s</filename>
<source>
<database>My Database</database>
<annotation>COCO</annotation>
<image>flickr</image>
<flickrid>NULL</flickrid>
</source>
<owner>
<flickrid>NULL</flickrid>
<name>company</name>
</owner>
<size>
<width>%d</width>
<height>%d</height>
<depth>%d</depth>
</size>
<segmented>0</segmented>
"""
objstr = """\
<object>
<name>%s</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>%d</xmin>
<ymin>%d</ymin>
<xmax>%d</xmax>
<ymax>%d</ymax>
</bndbox>
</object>
"""
tailstr = '''\
</annotation>
'''
# 检查目录是否存在,如果存在,先删除再创建,否则,直接创建
def mkr(path):
if not os.path.exists(path):
os.makedirs(path) # 可以创建多级目录
def id2name(coco):
classes = dict()
for cls in coco.dataset['categories']:
classes[cls['id']] = cls['name']
return classes
def write_xml(anno_path, head, objs, tail):
f = open(anno_path, "w")
f.write(head)
for obj in objs:
f.write(objstr % (obj[0], obj[1], obj[2], obj[3], obj[4]))
f.write(tail)
def save_annotations_and_imgs(coco, dataset, filename, objs):
# 将图片转为xml,例:COCO_train2017_000000196610.jpg-->COCO_train2017_000000196610.xml
dst_anno_dir = os.path.join(anno_dir, dataset)
mkr(dst_anno_dir)
anno_path = dst_anno_dir + '/' + filename[:-3] + 'xml'
img_path = dataDir + dataset + '/' + filename
# print("img_path: ", img_path)
dst_img_dir = os.path.join(img_dir, dataset)
mkr(dst_img_dir)
dst_imgpath = dst_img_dir + '/' + filename
# print("dst_imgpath: ", dst_imgpath)
img = cv2.imread(img_path)
# if (img.shape[2] == 1):
# print(filename + " not a RGB image")
# return
shutil.copy(img_path, dst_imgpath)
head = headstr % (filename, img.shape[1], img.shape[0], img.shape[2])
tail = tailstr
write_xml(anno_path, head, objs, tail)
def showimg(coco, dataset, img, classes, cls_id, show=True):
global dataDir
I = Image.open('%s/%s/%s' % (dataDir, dataset, img['file_name']))
# 通过id,得到注释的信息
annIds = coco.getAnnIds(imgIds=img['id'], catIds=cls_id, iscrowd=None)
# print(annIds)
anns = coco.loadAnns(annIds)
# print(anns)
# coco.showAnns(anns)
objs = []
for ann in anns:
class_name = classes[ann['category_id']]
if class_name in classes_names:
# print(class_name)
if 'bbox' in ann:
bbox = ann['bbox']
xmin = int(bbox[0])
ymin = int(bbox[1])
xmax = int(bbox[2] + bbox[0])
ymax = int(bbox[3] + bbox[1])
obj = [class_name, xmin, ymin, xmax, ymax]
objs.append(obj)
draw = ImageDraw.Draw(I)
draw.rectangle([xmin, ymin, xmax, ymax])
if show:
plt.figure()
plt.axis('off')
plt.imshow(I)
plt.show()
return objs
for dataset in datasets_list:
# ./COCO/annotations/instances_train2017.json
annFile = '{}/annotations/instances_{}.json'.format(dataDir, dataset)
# 使用COCO API用来初始化注释数据
coco = COCO(annFile)
# 获取COCO数据集中的所有类别
classes = id2name(coco)
# print(classes)
# [1, 2, 3, 4, 6, 8]
classes_ids = coco.getCatIds(catNms=classes_names)
# print(classes_ids)
for cls in classes_names:
# 获取该类的id
cls_id = coco.getCatIds(catNms=[cls])
img_ids = coco.getImgIds(catIds=cls_id)
# print(cls, len(img_ids))
# imgIds=img_ids[0:10]
for imgId in tqdm(img_ids):
img = coco.loadImgs(imgId)[0]
filename = img['file_name']
# print(filename)
objs = showimg(coco, dataset, img, classes, classes_ids, show=False)
# print(objs)
save_annotations_and_imgs(coco, dataset, filename, objs)
# 文件夹文件计数
#
import os
def count_files_in_folder(folder_path):
try:
# 获取文件夹中的所有文件和子文件夹
items = os.listdir(folder_path)
# 初始化计数器
file_count = 0
# 遍历文件夹中的所有项目
for item in items:
item_path = os.path.join(folder_path, item)
# 判断是否为文件
if os.path.isfile(item_path):
file_count += 1
# 如果是子文件夹,则递归调用count_files_in_folder
elif os.path.isdir(item_path):
file_count += count_files_in_folder(item_path)
return file_count
except Exception as e:
print(f"Error counting files: {e}")
return None
# 测试示例
folder_path = "/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB_faceDB_v2/label"
result = count_files_in_folder(folder_path)
if result is not None:
print(f"Number of files in {folder_path}: {result}")
import os
directory = "/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB_faceDB/JPEGImages"
# prefix = "smoB_"
prefix = "smoA_"
# prefix = "phoneA_"
# prefix = "ph"
# prefix = "drB_"
# prefix = "dr"
# prefix = "phoneB_"
# 获取目录中所有文件名
files = os.listdir(directory)
# 过滤出以指定前缀开头的文件
filtered_files = [file for file in files if file.startswith(prefix)]
# 按照修改时间排序,保留最新的50个文件
sorted_files = sorted(filtered_files, key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True)
files_to_delete = sorted_files[50:]
# 删除文件
for file in files_to_delete:
file_path = os.path.join(directory, file)
os.remove(file_path)
# 检测两个文件夹文件是否匹配 不匹配删除
# delete
import os
image_folder = r'/home/ws/CoodWorkRun/Database/testdb/JPEGImages'
label_folder = r'/home/ws/CoodWorkRun/Database/testdb/label'
# 获取图片文件夹和标签文件夹内的所有文件名
# 获取图片文件夹和标签文件夹内的所有文件名(去掉后缀)
image_files = set(os.path.splitext(filename)[0] for filename in os.listdir(image_folder))
label_files = set(os.path.splitext(filename)[0] for filename in os.listdir(label_folder))
print(image_files)
print(len(image_files))
print(label_files)
print(len(label_files))
# 找出需要删除的文件
files_to_delete = image_files.symmetric_difference(label_files)
print('删除文件夹:')
print(files_to_delete)
print('删除数:')
print(len(files_to_delete))
# # 删除不匹配的文件
# for filename in files_to_delete:
# # print(filename)
# if filename in image_files:
# os.remove(os.path.join(image_folder, filename+'.jpg'))
# if filename in label_files:
# os.remove(os.path.join(label_folder, filename+'.txt'))
# 数据集划分
#
import os
import random
import shutil
# 原始数据存放路径
data_dir = r"/home/ws/CoodWorkRun/Database/HeadDB/"
images_dir = os.path.join(data_dir, "JPEGImages")
labels_dir = os.path.join(data_dir, "label")
# 划分后的训练集和验证集路径
train_dir = "/home/ws/CoodWorkRun/Database/HeadDB/train"
train_images_dir = os.path.join(train_dir, "images")
train_labels_dir = os.path.join(train_dir, "labels")
val_dir = "/home/ws/CoodWorkRun/Database/HeadDB/val"
val_images_dir = os.path.join(val_dir, "images")
val_labels_dir = os.path.join(val_dir, "labels")
# 创建训练集和验证集目录
os.makedirs(train_images_dir, exist_ok=True)
os.makedirs(train_labels_dir, exist_ok=True)
os.makedirs(val_images_dir, exist_ok=True)
os.makedirs(val_labels_dir, exist_ok=True)
# 获取所有图片文件名
image_files = os.listdir(images_dir)
# 随机打乱文件列表
random.shuffle(image_files)
# 计算划分的数量
total_images = len(image_files)
train_ratio = 0.9
num_train = int(total_images * train_ratio)
# 将图片和标签文件划分到训练集和验证集
train_file_list = []
val_file_list = []
for i, image_file in enumerate(image_files):
label_file = image_file.replace(".jpg", ".txt")
if i < num_train:
# 划分到训练集
shutil.copy(os.path.join(images_dir, image_file), os.path.join(train_images_dir, image_file))
shutil.copy(os.path.join(labels_dir, label_file), os.path.join(train_labels_dir, label_file))
train_file_list.append(os.path.join("train", "images", image_file))
else:
# 划分到验证集
shutil.copy(os.path.join(images_dir, image_file), os.path.join(val_images_dir, image_file))
shutil.copy(os.path.join(labels_dir, label_file), os.path.join(val_labels_dir, label_file))
val_file_list.append(os.path.join("val", "images", image_file))
# 创建train.txt和val.txt文件
with open(os.path.join(data_dir, "train.txt"), "w") as train_txt_file:
train_txt_file.write("\n".join(train_file_list))
with open(os.path.join(data_dir, "val.txt"), "w") as val_txt_file:
val_txt_file.write("\n".join(val_file_list))
print(f"划分完成,训练集包含 {num_train} 个样本,验证集包含 {total_images - num_train} 个样本。")
# 检查txt文件夹内文件内容是否为空
import os
folder_path = "/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB/label"
empty_files = []
for file_name in os.listdir(folder_path):
if file_name.endswith(".txt"):
file_path = os.path.join(folder_path, file_name)
if os.path.getsize(file_path) == 0:
empty_files.append(file_name)
print("Empty file:", file_name)
num_empty_folders = len(empty_files)
print("Number of empty files:", num_empty_folders)
# 人脸数据集提取
import shutil
import os
# 指定原始文件夹和新文件夹的路径
original_folder = r'/home/ws/CoodWorkRun/Database/人脸数据集w/faceDB/JPEGImages'
new_folder = r'/home/ws/CoodWorkRun/Database/人脸数据集w/faceDB20K/JPEGImages'
# 指定要提取的文件范围
start_index = 10001
end_index = 30000
# 遍历原始文件夹中的文件
for filename in os.listdir(original_folder):
# 提取文件编号
file_index = int(filename.split('_')[1].split('.')[0])
# 如果文件编号在指定范围内,则复制文件到新文件夹
if start_index <= file_index <= end_index:
file_path = os.path.join(original_folder, filename)
shutil.copy(file_path, new_folder)
# 人脸数据集提取
import shutil
import os
# 设置原始文件夹路径和目标文件夹路径
source_folder = r'/home/ws/CoodWorkRun/Database/人脸数据集w/faceDB10K/label'
target_folder = r'/home/ws/CoodWorkRun/Database/人脸数据集w/faceDB20K/label'
# 判断目标文件夹是否存在,如果不存在则创建
if not os.path.exists(target_folder):
os.makedirs(target_folder)
# 遍历源文件夹中的所有文件,将需要提取的文件复制到目标文件夹中
for filename in os.listdir(source_folder):
if 'faceA_010001' <= filename <= 'faceA_030001':
source_path = os.path.join(source_folder, filename)
target_path = os.path.join(target_folder, filename)
shutil.copyfile(source_path, target_path)
# 人脸数据集标签制作
from PIL import Image,ImageDraw
anno_box_path = r"/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/Anno/list_bbox_celeba.txt"
label_dir = "/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/label"
img_dir = "/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/Img/img_celeba.7z/img_celeba"
count = 0
epoch = 1
box_file = open(anno_box_path,"r")
i = 0
for line in box_file:
if i < 2:
i += 1
continue
i += 1
print(line)
imgname = line[0:6]
#print(imgname)
img_strs = line.split()
x1, y1, w, h = int(img_strs[1]), int(img_strs[2]), int(img_strs[3]), int(img_strs[4])
x2, y2 = x1+w, y1+h
img = Image.open(f"{img_dir}/{img_strs[0]}")
img_w, img_h = img.size
# ****************************
dw = 1. / (int(img_w))
dh = 1. / (int(img_h))
x = ((x1 + x2) / 2.0 - 1)*dw
y = ((y1 + y2) / 2.0 - 1)*dh
w = (x2 - x1)*dw
h = (y2 - y1)*dh
# x = x * dw
# w = w * dw
# y = y * dh
# h = h * dh
# ****************************
label_txt = open(f"{label_dir}/{imgname}.txt", "w")
label_txt.write(f"0 {x} {y} {w} {h}\n")
label_txt.flush()
label_txt.close()
if i == 1:
exit()
import os
import requests
from tqdm import tqdm
url = 'https://dorc.ks3-cn-beijing.ksyun.com/data-set/2020Objects365%E6%95%B0%E6%8D%AE%E9%9B%86/train/'
# 图片路径
directory = 'E:\objects365\images'
# 创建目录(如果不存在)
os.makedirs(directory, exist_ok=True)
# 切换到目录
os.chdir(directory)
for f in tqdm(range(51)):
file_url = url + 'patch' + str(f) + '.tar.gz'
file_name = 'patch' + str(f) + '.tar.gz'
# print('Downloading', file_url, '...')
response = requests.get(file_url, stream=True)
total_size = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True)
with open(file_name, 'wb') as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
if total_size != 0 and progress_bar.n != total_size:
print("Download failed.")
exit()
print('Download complete.')
# 标签文件重命名
import os
def rename_files(folder_path_images, folder_path_labels):
try:
# 获取两个文件夹中的文件列表
image_files = sorted(os.listdir(folder_path_images))
label_files = sorted(os.listdir(folder_path_labels))
# 确保两个文件夹中的文件数量相同
if len(image_files) != len(label_files):
print("Error: The number of files in the two folders does not match.")
return
# 遍历文件列表,对应重命名文件
for image_file, label_file in zip(image_files, label_files):
image_old_path = os.path.join(folder_path_images, image_file)
label_old_path = os.path.join(folder_path_labels, label_file)
# 获取文件名和扩展名
image_name, image_ext = os.path.splitext(image_file)
# 生成新的文件名
new_name = f"phoneB_{image_name}"
# 构建新的文件路径
image_new_path = os.path.join(folder_path_images, f"{new_name}{image_ext}")
label_new_path = os.path.join(folder_path_labels, f"{new_name}.txt")
# 重命名文件
os.rename(image_old_path, image_new_path)
os.rename(label_old_path, label_new_path)
print("Files renamed successfully.")
except Exception as e:
print(f"Error: {e}")
# 使用示例
folder_path_images = r'C:\Users\User\Desktop\coco\transfer\cell_phone\JPEGImages'
folder_path_labels = r'C:\Users\User\Desktop\coco\transfer\cell_phone\label'
rename_files(folder_path_images, folder_path_labels)
# xml转txt标签文件
#
import xml.etree.ElementTree as ET
from os import listdir, getcwd
import glob
import cv2
# folder_path_images = r'C:\Users\User\Desktop\coco\transfer\bottle\JPEGImages'
# folder_path_labels = r'C:\Users\User\Desktop\coco\transfer\bottle\annotations'
classes = ["cell phone"] # <name>person</name>,中是啥填啥,多个用逗号隔开
def convert(size, box):
# 新增对框框范围的判断,防止0作为被除数
if size[0] == 0:
dw = size[0]
else:
dw = 1.0 / size[0]
if size[1] == 0:
dw = size[1]
else:
dh = 1.0 / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
# return (x, y, w, h)
return ('%.6f' % x, '%.6f' % y, '%.6f' % w, '%.6f' % h)
def convert_annotation(image_name, image_path):
print(f"Processing {image_name}")
# print(image_name[0:-3])
f = open(r'C:\Users\User\Desktop\coco\transfer\cell_phone\annotations/' + image_name[0:-3] + 'xml', encoding="utf8") # xml文件存放文件夹路径
out_file = open(r'C:\Users\User\Desktop\coco\transfer\cell_phone/label/' + image_name[0:-3] + 'txt', 'w') # 存放转换后的txt文件路径,记得先创建label文件夹
xml_text = f.read()
root = ET.fromstring(xml_text)
f.close()
size = root.find('size')
# 填补图片高宽缺失
img = cv2.imread(image_path)
sz = img.shape
w = int(sz[1])
h = int(sz[0])
# w = int(size.find('width').text)
# h = int(size.find('height').text)
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
# print(cls)
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
float(xmlbox.find('ymax').text))
bb = convert((w, h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
if __name__ == '__main__':
for image_path in glob.glob(r"C:\Users\User\Desktop\coco\transfer\cell_phone/JPEGImages/*.jpg"): # 放图片的文件夹,自己图片什么类型,自行替换
image_name = image_path.split('\\')[-1]
# print(image_name)
convert_annotation(image_name, image_path)
print('完成!')