目标检测图像数据预处理阶段常用的脚本集合

编程入门 行业动态 更新时间:2024-10-11 11:22:18

目标检测图像数据预处理阶段常用的<a href=https://www.elefans.com/category/jswz/34/1771291.html style=脚本集合"/>

目标检测图像数据预处理阶段常用的脚本集合

保持图片格式统一

import os
import cv2 as cvimage_path = 'J:/102HorizontalProject/zong/image'    #设置图片读取的路径
save_path = 'J:/yolov5-master-cow/data/images'    #设置图片保存的路径if not os.path.exists(save_path):    #判断路径是否正确,如果正确就打开os.makedirs(save_path)image_file = os.listdir(image_path)for image in image_file:if image.split('.')[-1] in ['bmp', 'jpg', 'jpeg', 'png', 'JPG', 'PNG']:str = image.rsplit(".", 1)    #从右侧判断是否有符号“.”,并对image的名称做一次分割。如112345.jpeg分割后的str为["112345","jpeg"]output_img_name = str[0] + ".jpg"    #取列表中的第一个字符串与“.jpg”放在一起。src = cv.imread(os.path.join(image_path, image))newimg = cv.imwrite(save_path + '/' + output_img_name, src)
print('FINISHED')

拍照后的图像进行缩放resize到指定长宽大小。用到cv2。

import os
import cv2'''设置原始图片存放路径,不能有中文'''
datadir = "F:/picdata/SISD10raw/"'''设置目标像素大小,此处设为1280'''
IMG_SIZE = 1280'''使用os.path模块的join方法生成路径'''
path = os.path.join(datadir)'''使用os.listdir(path)函数,返回path路径下所有文件的名字,以及文件夹的名字'''
img_list = os.listdir(path)for i in img_list:img_array = cv2.imread(os.path.join(path, i), cv2.IMREAD_COLOR)'''调用cv2.resize函数resize图片'''new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))img_name = str(i)  # 保存的图片与处理前图片同名'''生成图片存储的目标路径'''save_path = 'F:/picdata/SISD10/'+str(i)'''调用cv.2的imwrite函数保存图片'''cv2.imwrite(save_path, new_array)

jpg图片名字批量重命名rename,总位数一致,都是0开头,右对齐。

import osdef myrename(path):file_list = os.listdir(path)for i, fi in enumerate(file_list):old_dir = os.path.join(path, fi)filename = str(i + 1) + "." + str(fi.split(".")[-1])new_dir = os.path.join(path, filename)try:os.rename(old_dir, new_dir)except Exception as e:print(e)print("Failed!")else:print("SUcess!")if __name__ == "__main__":path = r"F:/picdata/SISD10"myrename(path)# myrename执行后图片按1,2,3,,,,顺序# 执行后面的代码,将进一步修改为00001,00002,00003,,,,filelist = os.listdir(path)filetype = '.jpg'for file in filelist:Olddir = os.path.join(path, file)if os.path.isdir(Olddir):continue# os.path.splitext("path"):分离文件名与扩展名filename = os.path.splitext(file)[0]filetype = os.path.splitext(file)[1]print(filename.zfill(5))# zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0Newdir = os.path.join(path, filename.zfill(5) + filetype)  # 数字5是定义为5位数,可随意修改需要的print(Newdir)os.rename(Olddir, Newdir)

 多人协同打标的情况下,xml文件路径可能不同,   需要把 <path>F:\picdata\SISD10\00001.jpg</path>

批量改成G盘目录,保持一致。注意转义符\\

<path>G:\picdata\SISD10\00001.jpg</path>

多字段要替换,就继续用if

import osif __name__=='__main__':work_dir = 'F:/picdata/test/test1/'new_dir = 'F:/picdata/test/test2/'for parent, dirnames, filenames in os.walk(work_dir,  followlinks=True):for filename in filenames:file_path = os.path.join(parent, filename)file = open(file_path,"r+",encoding='UTF-8')newFile = open(new_dir + filename,"w",encoding='UTF-8')for line in file.readlines():if("F:\\" in line):line = line.replace("F:\\","G:\\")newFile.writelines(line)print (filename)newFile.close()file.close()

 yolov7需要的数据文件结构,如果已经有yolov5格式划分好的数据集,如

datasets
├─images
│  ├─test
│  ├─train
│  └─val
├─labels├─test├─train└─val

则用这个代码生成datasets目录下3个txt文件:train.txtval.txttest.txt

参考:

import os
from tqdm import tqdmif __name__ == '__main__':rootdir = 'G:/A_lwd_paper/linetrash_datasets_new/A_data_samewithautol911'rootimagesdir = os.path.join(rootdir, 'images')rootlabelsdir = os.path.join(rootdir, 'labels')assert os.path.exists(rootimagesdir), f'{rootimagesdir} not exists.'assert os.path.exists(rootlabelsdir), f'{rootlabelsdir} not exists.'imagesets = ['train', 'val', 'test']    # 将images/train val test中的图像的绝对地址分别写入txt中for sets in imagesets:imagesdir = os.path.join(rootimagesdir, sets)with open(os.path.join(rootdir, f'{sets}.txt'), 'w') as f:filelist = os.listdir(imagesdir)for images in tqdm(filelist):f.write(os.path.join(imagesdir, images) + '\n')

labelme2voc

#!/usr/bin/env pythonfrom __future__ import print_functionimport argparse
import glob
import os
import os.path as osp
import sysimport imgviz
import numpy as npimport labelmedef main():parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)parser.add_argument("input_dir", help="input annotated directory")parser.add_argument("output_dir", help="output dataset directory")parser.add_argument("--labels", help="labels file", required=True)parser.add_argument("--noviz", help="no visualization", action="store_true")args = parser.parse_args()if osp.exists(args.output_dir):print("Output directory already exists:", args.output_dir)sys.exit(1)os.makedirs(args.output_dir)os.makedirs(osp.join(args.output_dir, "JPEGImages"))os.makedirs(osp.join(args.output_dir, "SegmentationClass"))os.makedirs(osp.join(args.output_dir, "SegmentationClassPNG"))if not args.noviz:os.makedirs(osp.join(args.output_dir, "SegmentationClassVisualization"))os.makedirs(osp.join(args.output_dir, "SegmentationObject"))os.makedirs(osp.join(args.output_dir, "SegmentationObjectPNG"))if not args.noviz:os.makedirs(osp.join(args.output_dir, "SegmentationObjectVisualization"))print("Creating dataset:", args.output_dir)class_names = []class_name_to_id = {}for i, line in enumerate(open(args.labels).readlines()):class_id = i - 1  # starts with -1class_name = line.strip()class_name_to_id[class_name] = class_idif class_id == -1:assert class_name == "__ignore__"continueelif class_id == 0:assert class_name == "_background_"class_names.append(class_name)class_names = tuple(class_names)print("class_names:", class_names)out_class_names_file = osp.join(args.output_dir, "class_names.txt")with open(out_class_names_file, "w") as f:f.writelines("\n".join(class_names))print("Saved class_names:", out_class_names_file)for filename in glob.glob(osp.join(args.input_dir, "*.json")):print("Generating dataset from:", filename)label_file = labelme.LabelFile(filename=filename)base = osp.splitext(osp.basename(filename))[0]out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg")out_cls_file = osp.join(args.output_dir, "SegmentationClass", base + ".npy")out_clsp_file = osp.join(args.output_dir, "SegmentationClassPNG", base + ".png")if not args.noviz:out_clsv_file = osp.join(args.output_dir,"SegmentationClassVisualization",base + ".jpg",)out_ins_file = osp.join(args.output_dir, "SegmentationObject", base + ".npy")out_insp_file = osp.join(args.output_dir, "SegmentationObjectPNG", base + ".png")if not args.noviz:out_insv_file = osp.join(args.output_dir,"SegmentationObjectVisualization",base + ".jpg",)img = labelme.utils.img_data_to_arr(label_file.imageData)imgviz.io.imsave(out_img_file, img)cls, ins = labelme.utils.shapes_to_label(img_shape=img.shape,shapes=label_file.shapes,label_name_to_value=class_name_to_id,)ins[cls == -1] = 0  # ignore it.# class labellabelme.utils.lblsave(out_clsp_file, cls)np.save(out_cls_file, cls)if not args.noviz:clsv = imgviz.label2rgb(cls,imgviz.rgb2gray(img),label_names=class_names,font_size=15,loc="rb",)imgviz.io.imsave(out_clsv_file, clsv)# instance labellabelme.utils.lblsave(out_insp_file, ins)np.save(out_ins_file, ins)if not args.noviz:instance_ids = np.unique(ins)instance_names = [str(i) for i in range(max(instance_ids) + 1)]insv = imgviz.label2rgb(ins,imgviz.rgb2gray(img),label_names=instance_names,font_size=15,loc="rb",)imgviz.io.imsave(out_insv_file, insv)if __name__ == "__main__":main()

xml_to_yolo_rotation

类别,cx,cy,w,h,angle

#!/usr/bin/env python
# coding: utf-8# ## convert xml to [yolov5-rotation]() format. [旋转版yolov5]()标签格式转换# In[1]:import xml.etree.ElementTree as ET
from tqdm import tqdm # pip install tqdm
import os
import math# In[2]:workdir = 'H:/picdata/' # datasets root path. 数据集路径
images_dir = os.path.join(workdir, 'SISD10') # images path. 图像路径
labels_dir = os.path.join(workdir, 'SID10rotatelabelxml') # xml labels path. xml标签路径
# yolov5_all_images = os.path.join(workdir, 'yolov5_all_images') # all images for yolov5 rotation. 转换后旋转版yolov5可用的图像路径
yolov5_all_labels = os.path.join(workdir, 'SID10rotatetxt') # all labels for yolov5 rotation. 转换后旋转版yolov5可用的txt标签路径
for d in [yolov5_all_labels]:if not os.path.exists(d):os.mkdir(d)# In[3]:all_files = [i for i in os.listdir(labels_dir) if i[-4:] == '.xml']# In[4]:print('labels count: ', len(all_files))# In[5]:#todo
keep_class_names = ['cup','forceps','kidneydish','needleholder','retractor','scalpel','scalpelhandle','scissors','sutureneedle','tampon'] # auto scan if blank. 如果留空,会自动扫描类别# In[6]:class_names = dict(zip(keep_class_names, range(len(keep_class_names))))# ## convert. 转换# In[7]:auto_scan = False
class_index = 0
if len(class_names) == 0:auto_scan = Trueprint('Auto scan classnames enabled.')for file in tqdm(all_files):file_path = os.path.join(labels_dir, file)tree = ET.parse(file_path)root = tree.getroot()img_size = root.find('size')width = float(img_size.find('width').text)height = float(img_size.find('height').text)objs = root.findall('object')with open(os.path.join(yolov5_all_labels, file[:-4] + '.txt'), 'w+') as f:for obj in objs:name = obj.find('name').text.strip()if name not in class_names.keys():if auto_scan:class_names[name] = class_indexclass_index = class_index + 1else:continuerbb = obj.find('robndbox')if not rbb:print('no robndbox in %s' % (file_path))cx = float(rbb.find('cx').text)cy = float(rbb.find('cy').text)w = float(rbb.find('w').text)h = float(rbb.find('h').text)angle = float(rbb.find('angle').text)if angle > math.pi:angle = angle - math.pidegree = round(angle / math.pi * 180)if h > w:     # swap w,h if w is not longside. 宽不是长边时,交换宽高w, h = h, wif degree < 90:degree = degree + 90else:degree = degree - 90cv_degree = degree # 180 - degree     # opencv angle format. opencv格式角度if cv_degree == 180:cv_degree = 0assert cv_degree >= 0 and cv_degree < 180f.write('{} {} {} {} {} {}\n'.format(class_names[name], cx/width, cy/height, w/width, h/height, cv_degree))# break# In[8]:print('class_names: ', class_names)# In[9]:sorted_keys = [i[0] for i in sorted(class_names.items(), key = lambda kv:(kv[1], kv[0]))]# In[10]:print('names: [ "{}" ]'.format('", "'.join(sorted_keys)))

yolo_rotation_to_xml

旋转yolo转回到xml文件。angle角度稍微有小数点后3位误差,原因可能是txt中保留的小数点位数,原xml转txt约了一次。txt转回xml又约了一次。原xml中w和h不一定w>h,但转出到txt一定是w>h,再转回xml时,和原xml不一样。

# 参考 .html
# 参考 
import os
# import xml.etree.ElementTree as ET
from lxml import etree as ET
from PIL import Image
import numpy as np
import math
# 图片文件夹
img_path = 'E:\picdata\SISD10\\'# txt文件夹
labels_path = './SID10rotatelabeltxt/'# xml存放的文件夹
annotations_path = './test4/'labels = os.listdir(labels_path)# 类别
classes = ['cup','forceps','kidneydish','needleholder','retractor','scalpel','scalpelhandle','scissors','sutureneedle','tampon']  #类别名# 图片的高度、宽度、深度
sh =1280
sw =1280
sd =3def write_xml(imgname, sw, sh, sd, filepath, labeldicts):'''imgname: 没有扩展名的图片名称'''# 创建Annotation根节点root = ET.Element('annotation', {'verified': 'no'})ET.SubElement(root, 'folder').text = "SISD10"# 创建filename子节点,无扩展名                 ET.SubElement(root, 'filename').text = str(imgname)ET.SubElement(root, 'path').text = str(img_path+img_id+'.jpg')source = ET.SubElement(root,'source')ET.SubElement(source, 'database').text = "Unknown"# 创建size子节点 size = ET.SubElement(root,'size')ET.SubElement(size, 'width').text = str(sw)ET.SubElement(size, 'height').text = str(sh)ET.SubElement(size, 'depth').text = str(sd)ET.SubElement(root, 'segmented').text = "0"for labeldict in labeldicts:objects = ET.SubElement(root, 'object')ET.SubElement(objects, 'type').text = 'robndbox'ET.SubElement(objects, 'name').text = labeldict['name']ET.SubElement(objects, 'pose').text = 'Unspecified'ET.SubElement(objects, 'truncated').text = '0'ET.SubElement(objects, 'difficult').text = '0'robndbox = ET.SubElement(objects,'robndbox')ET.SubElement(robndbox, 'cx').text = str(round(labeldict['cx'],6))ET.SubElement(robndbox, 'cy').text = str(round(labeldict['cy'],6))ET.SubElement(robndbox, 'w').text = str(round(labeldict['w'],6))ET.SubElement(robndbox, 'h').text = str(round(labeldict['h'],6))ET.SubElement(robndbox, 'angle').text = str(round(labeldict['angle'],6))tree = ET.ElementTree(root)tree.write(filepath, encoding='utf-8',pretty_print=True)#每个元素会自动换行和缩进for label in labels:with open(labels_path + label, 'r') as f:img_id = os.path.splitext(label)[0]contents = f.readlines()labeldicts = []for content in contents:# 图片格式,我这里是jpg,你如果是png注意修改img = np.array(Image.open(img_path + label.strip('.txt') + '.jpg'))# 图片的高度、宽度、深度sh, sw, sd = img.shape[0], img.shape[1], img.shape[2]content = content.strip('\n').split()cx = float(content[1])*swcy = float(content[2])*shw = float(content[3])*swh = float(content[4])*shangle = float(content[5])*math.pi/180# 坐标的转换,x_center y_center width height angle -> cx cy w h anglenew_dict = {'name': classes[int(content[0])],'difficult': '0','cx': cx,'cy': cy,'w': w,'h': h,'angle': angle}labeldicts.append(new_dict)write_xml(img_id, sw, sh, sd, annotations_path + label.strip('.txt') + '.xml', labeldicts)print(img_id + '.txt to .xml is Done')

roxml2xml

.py

import xml.etree.ElementTree as ET
import math
import osdef rotate_point(point, angle, origin):angle_rad = math.radians(angle)  # 将角度angle从度数转换为弧度ox, oy = originpx, py = pointqx = ox + math.cos(angle_rad) * (px - ox) - math.sin(angle_rad) * (py - oy)qy = oy + math.sin(angle_rad) * (px - ox) + math.cos(angle_rad) * (py - oy)return qx, qydef rotate_bbox(bbox, angle, origin):rotated_bbox = []for point in bbox:rotated_point = rotate_point(point, angle, origin)rotated_bbox.append(rotated_point)return rotated_bboxdef process_xml(xml_path):tree = ET.parse(xml_path)root = tree.getroot()# Iterate through each object in the XML and update the bounding box coordinatesfor obj in root.findall('object'):robndbox = obj.find('robndbox')if robndbox is not None:cx = float(robndbox.find('cx').text)cy = float(robndbox.find('cy').text)w = float(robndbox.find('w').text)h = float(robndbox.find('h').text)angle = float(robndbox.find('angle').text)rotated_bbox = rotate_bbox([(cx, cy), (cx + w, cy), (cx + w, cy + h), (cx, cy + h)], angle, (cx, cy))min_x = min(rotated_bbox[0][0], rotated_bbox[3][0])max_x = max(rotated_bbox[1][0], rotated_bbox[2][0])min_y = min(rotated_bbox[0][1], rotated_bbox[1][1])max_y = max(rotated_bbox[2][1], rotated_bbox[3][1])# Create new <bndbox> elementsbndbox = ET.SubElement(obj, 'bndbox')xmin = ET.SubElement(bndbox, 'xmin')ymin = ET.SubElement(bndbox, 'ymin')xmax = ET.SubElement(bndbox, 'xmax')ymax = ET.SubElement(bndbox, 'ymax')# Set the values for <bndbox> elementsxmin.text = str(int(min_x))ymin.text = str(int(min_y))xmax.text = str(int(max_x))ymax.text = str(int(max_y))# Remove the <robndbox> elementobj.remove(robndbox)# Save the modified XML back to the original filetree.write(xml_path)# Specify the input directory containing XML files and the output directory
input_directory = r'F:\walyn\walyn\nanodet\retinal_hole\val_xml'# Iterate through each XML file in the input directory
for filename in os.listdir(input_directory):if filename.endswith('.xml'):xml_path = os.path.join(input_directory, filename)print(xml_path)process_xml(xml_path)print("Processing complete.")

xml_to_yolo_obb

4个点坐标(x,y) + 类别

# 文件名称   :roxml_to_dota.py
# 功能描述   :把rolabelimg标注的xml文件转换成dota能识别的xml文件,
#             再转换成dota格式的txt文件
#            把旋转框 cx,cy,w,h,angle,或者矩形框cx,cy,w,h,转换成四点坐标x1,y1,x2,y2,x3,y3,x4,y4
import os
import xml.etree.ElementTree as ET
import mathcls_list=['你的类别']
def edit_xml(xml_file, dotaxml_file):"""修改xml文件:param xml_file:xml文件的路径:return:"""tree = ET.parse(xml_file)objs = tree.findall('object')for ix, obj in enumerate(objs):x0 = ET.Element("x0")  # 创建节点y0 = ET.Element("y0")x1 = ET.Element("x1")y1 = ET.Element("y1")x2 = ET.Element("x2")y2 = ET.Element("y2")x3 = ET.Element("x3")y3 = ET.Element("y3")# obj_type = obj.find('bndbox')# type = obj_type.text# print(xml_file)if (obj.find('robndbox') == None):obj_bnd = obj.find('bndbox')obj_xmin = obj_bnd.find('xmin')obj_ymin = obj_bnd.find('ymin')obj_xmax = obj_bnd.find('xmax')obj_ymax = obj_bnd.find('ymax')#以防有负值坐标xmin = max(float(obj_xmin.text),0)ymin = max(float(obj_ymin.text),0)xmax = max(float(obj_xmax.text),0)ymax = max(float(obj_ymax.text),0)obj_bnd.remove(obj_xmin)  # 删除节点obj_bnd.remove(obj_ymin)obj_bnd.remove(obj_xmax)obj_bnd.remove(obj_ymax)x0.text = str(xmin)y0.text = str(ymax)x1.text = str(xmax)y1.text = str(ymax)x2.text = str(xmax)y2.text = str(ymin)x3.text = str(xmin)y3.text = str(ymin)else:obj_bnd = obj.find('robndbox')obj_bnd.tag = 'bndbox'  # 修改节点名obj_cx = obj_bnd.find('cx')obj_cy = obj_bnd.find('cy')obj_w = obj_bnd.find('w')obj_h = obj_bnd.find('h')obj_angle = obj_bnd.find('angle')cx = float(obj_cx.text)cy = float(obj_cy.text)w = float(obj_w.text)h = float(obj_h.text)angle = float(obj_angle.text)obj_bnd.remove(obj_cx)  # 删除节点obj_bnd.remove(obj_cy)obj_bnd.remove(obj_w)obj_bnd.remove(obj_h)obj_bnd.remove(obj_angle)x0.text, y0.text = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)x1.text, y1.text = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)x2.text, y2.text = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)x3.text, y3.text = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)# obj.remove(obj_type)  # 删除节点obj_bnd.append(x0)  # 新增节点obj_bnd.append(y0)obj_bnd.append(x1)obj_bnd.append(y1)obj_bnd.append(x2)obj_bnd.append(y2)obj_bnd.append(x3)obj_bnd.append(y3)tree.write(dotaxml_file, method='xml', encoding='utf-8')  # 更新xml文件# 转换成四点坐标
def rotatePoint(xc, yc, xp, yp, theta):xoff = xp - xc;yoff = yp - yc;cosTheta = math.cos(theta)sinTheta = math.sin(theta)pResx = cosTheta * xoff + sinTheta * yoffpResy = - sinTheta * xoff + cosTheta * yoffreturn str(int(xc + pResx)), str(int(yc + pResy))def totxt(xml_path, out_path):# 想要生成的txt文件保存的路径,这里可以自己修改files = os.listdir(xml_path)i=0for file in files:tree = ET.parse(xml_path + os.sep + file)root = tree.getroot()name = file.split('.')[0]output = out_path +'\\'+name + '.txt'file = open(output, 'w')i=i+1objs = tree.findall('object')for obj in objs:cls = obj.find('name').textbox = obj.find('bndbox')x0 = int(float(box.find('x0').text))y0 = int(float(box.find('y0').text))x1 = int(float(box.find('x1').text))y1 = int(float(box.find('y1').text))x2 = int(float(box.find('x2').text))y2 = int(float(box.find('y2').text))x3 = int(float(box.find('x3').text))y3 = int(float(box.find('y3').text))if x0<0:x0=0if x1<0:x1=0if x2<0:x2=0if x3<0:x3=0if y0<0:y0=0if y1<0:y1=0if y2<0:y2=0if y3<0:y3=0for cls_index,cls_name in enumerate(cls_list):if cls==cls_name:file.write("{} {} {} {} {} {} {} {} {} {}\n".format(x0, y0, x1, y1, x2, y2, x3, y3, cls,cls_index))file.close()# print(output)print(i)if __name__ == '__main__':# -----**** 第一步:把xml文件统一转换成旋转框的xml文件 ****-----roxml_path = r" 已标注并需要转换的xml文件"  dotaxml_path = r'存储dota格式的xml文件的输出路径'  #out_path = r'存储data格式yolov5_obb可训练的txt文件的路径'   filelist = os.listdir(roxml_path)for file in filelist:edit_xml(os.path.join(roxml_path, file), os.path.join(dotaxml_path, file))# -----**** 第二步:把旋转框xml文件转换成txt格式 ****-----totxt(dotaxml_path, out_path)

xml2yolo

import copy
from lxml.etree import Element, SubElement, tostring, ElementTreeimport xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import joinclasses = ["cup","forceps","kidneydish","needleholder","retractor","scapel","scapelhandle","scissors","sutureneedle","tampon"]  # 目标类别CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))def convert(size, box):dw = 1. / size[0]dh = 1. / size[1]x = (box[0] + box[1]) / 2.0y = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def convert_annotation(image_id):in_file = open('F:/picdata/SISD10label/%s.xml' % (image_id), encoding='UTF-8')  # xml文件路径out_file = open('F:/picdata/SISD10labelyolo/%s.txt' % (image_id), 'w')  # 生成txt格式文件tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):cls = obj.find('name').text# print(cls)if cls not in classes:continuecls_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')xml_path = os.path.join(CURRENT_DIR, 'F:/picdata/SISD10label')# xml list
img_xmls = os.listdir(xml_path)
for img_xml in img_xmls:label_name = img_xml.split('.')[0]print(label_name)convert_annotation(label_name)

json2txt

import json
import os
import glob
import os.path as ospdef labelme2yolov2Seg(jsonfilePath="", resultDirPath="", classList=["bowl","cup","forceps","kidneydish","needleholder","retractor","scapel","scapelhandle","sutureneedle","tampon"]):"""此函数用来将labelme软件标注好的数据集转换为yolov5_7.0sege中使用的数据集:param jsonfilePath: labelme标注好的*.json文件所在文件夹:param resultDirPath: 转换好后的*.txt保存文件夹:param classList: 数据集中的类别标签:return:"""# 0.创建保存转换结果的文件夹if(not os.path.exists(resultDirPath)):os.mkdir(resultDirPath)# 1.获取目录下所有的labelme标注好的Json文件,存入列表中jsonfileList = glob.glob(osp.join(jsonfilePath, "*.json"))print(jsonfileList)  # 打印文件夹下的文件名称# 2.遍历json文件,进行转换for jsonfile in jsonfileList:# 3. 打开json文件with open(jsonfile, "r") as f:file_in = json.load(f)# 4. 读取文件中记录的所有标注目标shapes = file_in["shapes"]# 5. 使用图像名称创建一个txt文件,用来保存数据with open(resultDirPath + "\\" + jsonfile.split("\\")[-1].replace(".json", ".txt"), "w") as file_handle:# 6. 遍历shapes中的每个目标的轮廓for shape in shapes:# 7.根据json中目标的类别标签,从classList中寻找类别的ID,然后写入txt文件中file_handle.writelines(str(classList.index(shape["label"])) + " ")# 8. 遍历shape轮廓中的每个点,每个点要进行图像尺寸的缩放,即x/width, y/heightfor point in shape["points"]:x = point[0]/file_in["imageWidth"]  # mask轮廓中一点的X坐标y = point[1]/file_in["imageHeight"]  # mask轮廓中一点的Y坐标file_handle.writelines(str(x) + " " + str(y) + " ")  # 写入mask轮廓点# 9.每个物体一行数据,一个物体遍历完成后需要换行file_handle.writelines("\n")# 10.所有物体都遍历完,需要关闭文件file_handle.close()# 10.所有物体都遍历完,需要关闭文件f.close()if __name__ == "__main__":jsonfilePath = "F:\picdata\SISD10dataset\data_annotated"  # 要转换的json文件所在目录resultDirPath = "F:\picdata\SISD10dataset\data_txt"  # 要生成的txt文件夹labelme2yolov2Seg(jsonfilePath=jsonfilePath, resultDirPath=resultDirPath, classList=["__ignore__","_background_","bowl","cup","forceps","kidneydish","needleholder","retractor","scapel","scapelhandle","sutureneedle","tampon"]) # 更改为自己的类别名

划分train val test

import os, shutil, random
import numpy as nppostfix = 'jpg'  # 这里要注意下,文件夹里的图片格式要都是jpg,如果是PNG那就都得是PNG
base_path = 'F:\数据集处理\SISD10dataset\img_data'   # 先手动把txt文件放进图片文件夹JPEGImages中
dataset_path = 'F:\数据集处理\SISD10dataset\SISD10seg'  # 自动新建一个文件夹SISDseg
val_size, test_size = 0.1, 0.0  # 这里把test设置为0,也就是train:val = 9:1
# val_size = 0.1os.makedirs(dataset_path, exist_ok=True)
os.makedirs(f'{dataset_path}/images', exist_ok=True)
os.makedirs(f'{dataset_path}/images/train', exist_ok=True)
os.makedirs(f'{dataset_path}/images/val', exist_ok=True)
os.makedirs(f'{dataset_path}/images/test', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/train', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/val', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/test', exist_ok=True)path_list = np.array([i.split('.')[0] for i in os.listdir(base_path) if 'txt' in i])
random.shuffle(path_list)
train_id = path_list[:int(len(path_list) * (1 - val_size - test_size))]
# train_id = path_list[:int(len(path_list) * (1 - val_size))]# val_id = path_list[int(len(path_list) * (1 - val_size - test_size)):int(len(path_list) * (1 - test_size))]
val_id = path_list[int(len(path_list) * (1 - val_size - test_size)):int(len(path_list) * (1 - test_size))]
test_id = path_list[int(len(path_list) * (1 - test_size)):]for i in train_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/train/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/train/{i}.txt')for i in val_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/val/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/val/{i}.txt')for i in test_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/test/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/test/{i}.txt')

anaconda 手动添加系统变量

Pycharm中Terminal用不了conda指令解决办法 

 PowerShell窗口

Set-ExecutionPolicy RemoteSigned

Y   回车

conda init powershell

conda配置国内镜像源将Anaconda设置为国内镜像源的方法_anaconda国内源_流沙没尘居士的博客-CSDN博客

conda config --add channels /
conda config --add channels /
conda config --add channels /
conda config --set show_channel_urls yes

改变conda虚拟环境的默认路径

创建新环境,并指定python版本

conda create --name=labelImg python=3.6

进入刚建立的新环境

conda activate labelimg

pip升级到最新版

python -m pip install --upgrade pip

pip配置国内镜像源

Python-pip镜像源配置及国内常用镜像源_pypi镜像源_KwokRoot的博客-CSDN博客

windows下:新建文件C:\Users\Administrator\pip\pip.ini 

[global]
index-url = 
[install]
trusted-host = 
pip install pyqt5pip install labelImg==1.8.6 -i / --trusted-host pypi.douban

(labelImg) F:\picdata>labelImg SISD10 predefined_classes.txt

..

..

更多推荐

目标检测图像数据预处理阶段常用的脚本集合

本文发布于:2024-02-11 23:49:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1684388.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:脚本   图像   阶段   常用   目标

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!