这批数据,名字带空格,需要先处理一下:
#-*-coding:utf-8-*-
import os
class BatchRename():
'''
批量重命名文件夹中的图片文件
'''
def __init__(self):
self.path = r'./JPEGImages' #表示需要命名处理的文件夹
def rename(self):
filelist = os.listdir(self.path) #获取文件路径
total_num = len(filelist) #获取文件长度(个数)
i = 1 #表示文件的命名是从1开始的
for item in filelist:
if item.endswith('.jpg'): #初始的图片的格式为jpg格式的(或者源文件是png格式及其他格式,后面的转换格式就可以调整为自己需要的格式即可)
src = os.path.join(os.path.abspath(self.path), item)
# dst = os.path.join(os.path.abspath(self.path), '2_' + str(i) + '.jpg')#处理后的格式也为jpg格式的,当然这里可以改成png格式
# dst = os.path.join(os.path.abspath(self.path), '002_' + str(i) + '.jpg')
dst = os.path.join(os.path.abspath(self.path), '0000' + format(str(i), '0>3s') + '.jpg') #这种情况下的命名格式为0000000.jpg形式,可以自主定义想要的格式
try:
os.rename(src, dst)
print('converting %s to %s ...' % (src, dst))
i = i + 1
src = src.replace("JPEGImages","Annotations")
src = src.replace(".jpg",".xml")
dst = dst.replace("JPEGImages","Annotations")
dst = dst.replace(".jpg",".xml")
os.rename(src, dst)
print('converting %s to %s ...' % (src, dst))
except:
continue
print('total %d to rename & converted %d jpgs' % (total_num, i))
if __name__ == '__main__':
demo = BatchRename()
demo.rename()
ImageSets/Main
生成数据的train.txt
#-*-coding:utf-8-*-
import os
import argparse
# description参数可以用于插入描述脚本用途的信息,可以为空
# 添加--verbose标签,标签别名可以为-v,这里action的意思是当读取的参数中出现--verbose/-v的时候
# 参数字典的verbose建对应的值为True,而help参数用于描述--verbose参数的用途或意义。
# 将变量以标签-值的字典形式存入args字典
def main(args):
'''main '''
flist = open('train.txt', 'w')
all_image = os.listdir('./' + args.file)
num = len(all_image)
number = 0
for im in all_image:
if(im.split('.')[-1] != 'jpg'):
continue
number += 1
im = im.split('.')[0]
print number, " / ", num
flist.write(im + '\n')
flist.close()
# https://www.cnblogs.com/arkenstone/p/6250782.html
def parse_args():
'''parse args'''
parser = argparse.ArgumentParser()
parser.add_argument('--file', '-f', default='source')
return parser.parse_args()
if __name__ == '__main__':
print False
print True
print("False %s" % (False))
print("True %s" % (True))
main(parse_args())
发现这批数据的XML格式与VOC格式不同:类别为1个
<?xml version="1.0" ?>
<doc>
<path>E:\4\bbk2\1 (219).jpg</path>
<outputs>
<object>
<item>
<name>book</name>
<bndbox>
<xmin>576</xmin>
<ymin>748</ymin>
<xmax>1988</xmax>
<ymax>2244</ymax>
</bndbox>
</item>
</object>
</outputs>
<time_labeled>1562292940774</time_labeled>
<labeled>true</labeled>
<size>
<width>2448</width>
<height>3264</height>
<depth>3</depth>
</size>
</doc>
<?xml version="1.0" ?>
<doc>
<path>E:\4\bbk2\1 (214).jpg</path>
<outputs></outputs>
<time_labeled>0</time_labeled>
<labeled>false</labeled>
</doc>
处理方式改变一下:
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2019', 'train')]
def convert(size, box):
dw = 1./size[0]
dh = 1./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)
def convert_annotation(year, image_id):
in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
if size==None:
return None
w = int(size.find('width').text)
h = int(size.find('height').text)
outputs = root.find('outputs')
objects = outputs.find('object')
out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
for obj in objects:
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(0) + " " + " ".join([str(a) for a in bb]) + '\n')
return 1
wd = getcwd()
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set))
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
print image_id
image_id = image_id.replace('\n','')
flag = convert_annotation(year, image_id)
if flag == 1:
list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
list_file.close()
顺便贴一下原始的python:
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
def convert(size, box):
dw = 1./size[0]
dh = 1./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)
def convert_annotation(year, image_id):
in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
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'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult) == 1:
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()
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
convert_annotation(year, image_id)
list_file.close()
重新用label的文件夹生成train.txt
因为JPEGImages中有部分不符合标准的xml:改一个地方就行:
if(im.split('.')[-1] != 'txt'):
#-*-coding:utf-8-*-
import os
import argparse
# description参数可以用于插入描述脚本用途的信息,可以为空
# 添加--verbose标签,标签别名可以为-v,这里action的意思是当读取的参数中出现--verbose/-v的时候
# 参数字典的verbose建对应的值为True,而help参数用于描述--verbose参数的用途或意义。
# 将变量以标签-值的字典形式存入args字典
def main(args):
'''main '''
flist = open('train.txt', 'w')
all_image = os.listdir('./' + args.file)
num = len(all_image)
number = 0
for im in all_image:
if(im.split('.')[-1] != 'txt'):
continue
number += 1
im = im.split('.')[0]
print number, " / ", num
flist.write(im + '\n')
flist.close()
# https://www.cnblogs.com/arkenstone/p/6250782.html
def parse_args():
'''parse args'''
parser = argparse.ArgumentParser()
parser.add_argument('--file', '-f', default='source')
return parser.parse_args()
if __name__ == '__main__':
print False
print True
print("False %s" % (False))
print("True %s" % (True))
main(parse_args())
接着:
在
darknet$ tree
.
├── data
│ ├── yolov3-tiny.name
│ └── yolov3.names
├── bad.list
├── cfg
│ ├── yolov3.cfg
│ ├── yolov3.data
│ ├── yolov3-tiny.cfg
│ └── yolov3-tiny.data
我们拿tiny举例子:
yolov3-tiny.name
book
yolov3-tiny.data
classes= 1
train = /home/boyun/data/VOCdevkit/VOC2019/train.txt
#valid = coco_testdev
#valid = data/coco_val_5k.list
names = data/yolov3.names
backup = ./backup/
#eval=coco
原始:
yolov3-tiny.cfg
[convolutional]
size=1
stride=1
pad=1
filters=255
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=80
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
更改:
[convolutional]
size=1
stride=1
pad=1
filters=18
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
./darknet detector train cfg/yolov3.data cfg/yolov3.cfg darknet53.conv.74 2>1 | tee ./backup/log.txt
./darknet detector train cfg/yolov3-tiny.data cfg/yolov3-tiny.cfg yolov3-tiny.weights 2>1 | tee ./backup/log.txt
我们这里不能使用tiny的预训练权重,因为改了一些参数
但是:
darknet53.conv.74
还是可以用的
./darknet detector test cfg/yolov3.data cfg/yolov3.cfg backup/yolov3_3000.weights ./data/one_2019_05_29_00000002.jpg
./darknet detector test cfg/yolov3-tiny.data cfg/yolov3-tiny.cfg backup/yolov3-tiny_3000.weights ./data/one_2019_05_29_00000002.jpg