⽬标检测⾃动标注⽣成xml⽂件⽂章⽬录
前⾔
⼀、使⽤opencv调⽤模型
此处以Darknet模型为例,使⽤OpenCV调⽤模型来检测图⽚中的⽬标。
#引⽤opencv-python库
import cv2
#此处设置相关的⽂件路径,我使⽤的时⼈脸检测的模型,所⽰是face.weights weightsPath ="./face/face.weights"
configPath ="./face/face.cfg"
labelsPath ="./face/face.names"
#读取names⽂件中的类别名
LABELS =open(labelsPath).read().strip().split("\n")
#使⽤opencv加载Darknet模型
net = adNetFromDarknet(configPath, weightsPath)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
#下⾯是通过检测获取坐标的函数
def coordinate_get(img):
coordinates_list=[]# 创建坐标列表
boxes =[]
confidences =[]
classIDs =[]
(H, W)= img.shape[:2]
# 得到 YOLO需要的输出层
ln = LayerNames()
ln =[ln[i[0]-1]for i UnconnectedOutLayers()]
# 从输⼊图像构造⼀个blob,然后通过加载的模型,给我们提供边界框和相关概率
blob = cv2.dnn.blobFromImage(img,1/255.0,(416,416), swapRB=True, crop=False) net.setInput(blob)
layerOutputs = net.forward(ln)
# 在每层输出上循环
for output in layerOutputs:
# 对每个检测进⾏循环
for detection in output:
scores = detection[5:]
classID = np.argmax(scores)
confidence = scores[classID]
# 过滤掉那些置信度较⼩的检测结果
if confidence >0.01:
# 框后接框的宽度和⾼度
box = detection[0:4]* np.array([W, H, W, H])
(centerX, centerY, width, height)= box.astype("int")
# 边框的左上⾓
x =int(centerX -(width /2))
y =int(centerY -(height /2))
# 更新检测出来的框
boxes.append([x, y,int(width),int(height)])
confidences.append(float(confidence))
classIDs.append(classID)
idxs = cv2.dnn.NMSBoxes(boxes, confidences,0.2,0.3)
if len(idxs)>0:
for i in idxs.flatten():
(x, y)=(boxes[i][0], boxes[i][1])
(w, h)=(boxes[i][2], boxes[i][3])
xmin =int(x)
ymin =int(y)
xmax =int(x + w)
ymax =int(y + h)
coordinates_list.append([xmin,ymin,xmax,ymax,classIDs[i]])
return coordinates_list
⼆、在xml⽂件中创建树并写⼊坐标
需要引⽤ElementTree来创建xml⽂件,并在xml⽂件中加⼊tree结构,相关函数如下:
import os
from os import getcwd
import ElementTree as ET
# 定义⼀个创建⼀级分⽀object的函数
def create_object(root,xi,yi,xa,ya,obj_name):# 参数依次,树根,xmin,ymin,xmax,ymax
#创建⼀级分⽀object
_object=ET.SubElement(root,'object')
#创建⼆级分⽀
name=ET.SubElement(_object,'name')
print(obj_name)
<=str(obj_name)
pose=ET.SubElement(_object,'pose')
<='Unspecified'
truncated=ET.SubElement(_object,'truncated')
<='0'
difficult=ET.SubElement(_object,'difficult')
<='0'
#创建bndbox
bndbox=ET.SubElement(_object,'bndbox')
xmin=ET.SubElement(bndbox,'xmin')
<='%s'%xi
ymin = ET.SubElement(bndbox,'ymin')
< ='%s'%yi
xmax = ET.SubElement(bndbox,'xmax')
< ='%s'%xa
ymax = ET.SubElement(bndbox,'ymax')
< ='%s'%ya
# 创建xml⽂件的函数
def create_tree(image_name, h, w):
global annotation
# 创建树根annotation
annotation = ET.Element('annotation')
#创建⼀级分⽀folder
folder = ET.SubElement(annotation,'folder')
#添加folder标签内容
<=(imgdir)
#创建⼀级分⽀filename
filename=ET.SubElement(annotation,'filename')
<=image_name
#创建⼀级分⽀path
path=ET.SubElement(annotation,'path')
<= getcwd()+'\{}\{}'.format(imgdir,image_name)# ⽤于返回当前⼯作⽬录
#创建⼀级分⽀source
source=ET.SubElement(annotation,'source')
#创建source下的⼆级分⽀database
database=ET.SubElement(source,'database')
<='Unknown'
#创建⼀级分⽀size
size=ET.SubElement(annotation,'size')
#创建size下的⼆级分⽀图像的宽、⾼及depth
width=ET.SubElement(size,'width')
<=str(w)
height=ET.SubElement(size,'height')
<=str(h)
depth = ET.SubElement(size,'depth')
< ='3'
#创建⼀级分⽀segmented
segmented = ET.SubElement(annotation,'segmented')
< ='0'
定义⼀个main函数
最后定义⼀个main函数:
for image_name in IMAGES_LIST:
#判断后缀只处理jpg⽂件
if dswith('jpg'):
image = cv2.imread(os.path.join(imgdir, image_name))
coordinates_list = coordinate_get(image)
(h, w)= image.shape[:2]
create_tree(image_name, h, w)
for coordinate in coordinates_list:
label_id = coordinate[4]
create_object(annotation, coordinate[0], coordinate[1], coordinate[2], coordinate[3], LABELS[label_id])
# if coordinates_list==[]:
# break
# 将树模型写⼊xml⽂件
tree = ET.ElementTree(annotation)
tree.write('.\{}\{}.xml'.format(imgdir, image_name.strip('.jpg')))
总结
python处理xml文件提⽰:在脚本运⾏前需要在python环境中安装opencv等依赖库。使⽤时修改模型配置⽂件的路径。注意main函数中有判断后缀的代码,如果图⽚不是jpg不会进⾏处理。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论