版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于via的课堂学生行为数据标注与
yolov7目标检测系统
源
代
码
README.md
#0via2yolo
via->yolo,yolo->via
via2yolo,是将via中标注的数据转化为yolo格式数据集,并且对数据集可视化与检测,检查包括数量上的
检查和小点的检查。
环境搭建:
```
condacreate--namevia2yolopython=3.8-y
```
激活环境:
```
condaactivatevia2yolo
```
退出环境:
```
condadeactivate
```
删除环境:
```
condaremove-nvia2yolo-all
```
安装opencv
```
pipinstallopencv-python-headless==0
```
#1via2yolo1.py
via2yolo1.py是将via转化为yolo格式
注意这是via中只框选了举手这个动作,就是将框转化为yolo格式,行为默认为0
```
pythonvia2yolo1.py--riseHand_via_dataset./riseHand_via_dataset--riseHand_Dataset./riseHand_Dataset
--tain_r0.8
```
#2viaExtendAction1.py
viaExtendAction1.py是对举手的数据集进行via标注扩展,扩展更多动作
```
pythonviaExtendAction1.py--Dataset_dir./Dataset--newDataset_dir./newDataset
```
#3via2yolo2.py
via2yolo2.py是将via转化为yolo格式
注意这是via中多个动作转化为yolo格式
并且可以检查没有标注的框,并给出没有标注的图片名字
```
1
pythonvia2yolo2.py--RRW_via_Dataset./RRW_via_Dataset--RRW_Dataset./RRW_Dataset--tain_r0.8
```
#2check.py
check.py的作用就是是检查via中的框的数量和yolo格式数据集的框的数量是否一致
```
pythoncheck.py--via_Dataset./riseHand_via_dataset--yolo_Dataset./riseHand_Dataset
```
#3visual.py
visual.py的作用可视化yolo数据集
```
pythonvisual.py--yolo_Dataset./riseHand_Dataset--Visual_dir./Visual
```
#4check_dot.py
check_dot.py是将找到小点对应的图片名字(图片名字中包含路径信息)
```
pythoncheck_dot.py--dot_size15--via_Dataset./riseHand_via_dataset
```
check.py
#该文件的作用就是是检查via中的框的数量和yolo格式数据集的框的数量是否一致
#pythoncheck.py--via_Dataset./riseHand_via_dataset--yolo_Dataset./riseHand_Dataset
importos
importjson
importcv2
importargparse
parser=argparse.ArgumentParser()
parser.add_argument('--via_Dataset',default='./riseHand_via_dataset',type=str)
parser.add_argument('--yolo_Dataset',default='./riseHand_Dataset',type=str)
arg=parser.parse_args()
#yolo数据集的存放位置yolo_Dataset
yolo_Dataset=arg.yolo_Dataset
#via数据集的存放位置via_Dataset
via_Dataset=arg.via_Dataset
#train_label_dir训练标签的位置
train_label_dir=os.path.join(yolo_Dataset,'labels/train')
#val_label_dir测试标签的位置
val_label_dir=os.path.join(yolo_Dataset,'labels/val')
#countBox是计算json文件中每张图片对应多少框
defcountBox(json,root):
#循环读出每一个框的信息,并且图片和框的数量存放在dict中
dict={}
foriinjson['metadata']:
#读取vid,一张图片中的所有框,vid是相同的
vid=i.split('_')[0]
#通过vid找到对应的图片
2
image_name=json['file'][vid]['fname']
#对图片中的框进行计数,如果第一次出现,进入else,计数为1,否则累加
ifimage_nameindict:
dict[image_name]=dict[image_name]+1
else:
dict[image_name]=1
returndict
#check_yolo是检查via中的框的数量和yolo格式数据集的框的数量是否一致
defcheck_yolo(dict_box):
#循环读取出每张图片中的检测框数量
forimage_nameindict_box:
#获取对应txt的名字和对应的路径
txt_name=image_name.split('.')[0]+'.txt'
#由于不知道txt位于train还是val中,所以需要都生成,然后判断。
txt_train_path=os.path.join(train_label_dir,txt_name)
txt_val_path=os.path.join(val_label_dir,txt_name)
#判断图片是在train中,还是在val中
ifos.path.exists(txt_train_path):
txt_path=txt_train_path
elifos.path.exists(txt_val_path):
txt_path=txt_val_path
else:
#如果txt不存在于train或者val中,报错
print("noexists:")
print(txt_train_path)
print(txt_val_path)
input()
#读取txt,计算出有多少行,每一行就代表一个框
txt_file=open(txt_path)
lines=len(txt_file.readlines())
#判断via中框的数量与txt的框的数量是否匹配。
ifnotlines==dict_box[image_name]:
print("error:",image_name)
input()
txt_file.close()
#循环读出所有json文件
forroot,dirs,filesinos.walk(via_Dataset,topdown=False):
fornameinfiles:
file_dir=os.path.join(root,name)
if'.json'inname:
file_json=open(file_dir,'r')
file_json_content=json.loads(file_json.read())
3
dict_box=countBox(file_json_content,root)
file_json.close()
check_yolo(dict_box)
print(name)
check_dot.py
#这一段代码是将找到小点对应的图片名字(图片名字中包含路径信息)
#pythoncheck_dot.py--dot_size15--via_Dataset./riseHand_via_dataset
importos
importjson
importargparse
parser=argparse.ArgumentParser()
#dot_size是调整筛选小点的阈值
parser.add_argument('--dot_size',default=15,type=int)
parser.add_argument('--via_Dataset',default='./riseHand_via_dataset',type=str)
arg=parser.parse_args()
dot_size=arg.dot_size
via_Dataset=arg.via_Dataset
#计数有多少小点
dot_num=0
#countBox是计算json文件中每张图片对应多少框
defsearch_dot(json,root):
globaldot_num
#循环读出每一个框的信息,并且图片和框的数量存放在dict中
dict={}
foriinjson['metadata']:
#读取vid,一张图片中的所有框,vid是相同的
vid=i.split('_')[0]
#通过vid找到对应的图片
image_name=json['file'][vid]['fname']
#读取坐标信息
xy=json['metadata'][i]['xy']
#xy[3],xy[4]是wh,如果w或者h都小于阈值,则判定为小点
iffloat(xy[3])<dot_sizeorfloat(xy[4])<dot_size:
print("dot:",image_name)
dot_num=dot_num+1
#循环读出所有json文件
forroot,dirs,filesinos.walk(via_Dataset,topdown=False):
fornameinfiles:
file_dir=os.path.join(root,name)
if'.json'inname:
file_json=open(file_dir,'r')
file_json_content=json.loads(file_json.read())
search_dot(file_json_content,root)
4
print("dot_num:",dot_num)
via2yolo.py
#这一段代码是将via转化为yolo格式
#pythonvia2yolo.py--Via_Dataset_dir./riseHand_via_dataset--Dataset_dir./riseHand_Dataset--tain_r0.8
#注意这是via中只框选了举手这个动作,就是将框转化为yolo格式,行为默认为0
#注意,这个不兼容windows系统
importos
importjson
importcv2
importrandom
importargparse
parser=argparse.ArgumentParser()
parser.add_argument('--Via_Dataset_dir',default='./via_dataset',type=str)
parser.add_argument('--Dataset_dir',default='./Dataset',type=str)
parser.add_argument('--tain_r',default=0.65,type=float)
arg=parser.parse_args()
Via_Dataset_dir=arg.Via_Dataset_dir
#yolo数据集的存放位置Dataset_dir
Dataset_dir=arg.Dataset_dir
#清空Dataset_dir下的文件及文件夹
os.system('rm-r'+Dataset_dir+'/*')
#在Dataset_dir下创建labelsimagestrainval
os.system('mkdir-p'+Dataset_dir+'/{labels,images}/{train,val}')
#训练集与验证集的比例,tain_r代表训练集的比例,1-tain_r代表验证集的比例
tain_r=arg.tain_r
#设置labelsimagestrainval的路径
train_label_dir=Dataset_dir+'/labels/train/'
val_label_dir=Dataset_dir+'/labels/val/'
train_image_dir=Dataset_dir+'/images/train/'
val_image_dir=Dataset_dir+'/images/val/'
#via2yolo函数是将via信息转化为yolo的格式
defvia2yolo(json,root):
#循环读出每一个框的信息
foriinjson['metadata']:
#从i中获取vid
vid=i.split('_')[0]
#获取对应的图片名字
image_name=json['file'][vid]['fname']
#获取图片的路径
image_dir=os.path.join(root,image_name)
#读取图片的高和宽
img=cv2.imread(image_dir)
5
h=img.shape[0]
w=img.shape[1]
#读取via中的坐标xywh,框的左上角坐标xy,与框的宽高
xywh=json['metadata'][i]['xy'][1:]
'''
将xywh转化为yolo的格式
第一个参数是0,代表举手这一个分类
第二个参数是,框的中心坐标x,归一化处理
第三个参数是,框的中心坐标y,归一化处理
第四个参数是,框的宽度w,归一化处理
第五个参数是,框的高度h,归一化处理
第六个参数是,换行
'''
xcyc_wh='0'+str((xywh[0]+xywh[2]/2)/w)+''+str((xywh[1]+xywh[3]/2)/h)+\
''+str(xywh[2]/w)+''+str(xywh[3]/h)+'\n'
#设置txt的train和val的路径
temp_train_txt_path=os.path.join(train_label_dir,image_name.split('.')[0]+'.txt')
temp_val_txt_path=os.path.join(val_label_dir,image_name.split('.')[0]+'.txt')
'''
判断当前的temp_train_txt_path或者temp_val_txt_path是否已经存在
如果不存在,就进入if中
不存在代表已经进入下一个图片的框了,需要创建一个新的txt
如果存在,就进入else中
'''
ifnot(os.path.isfile(temp_train_txt_path)oros.path.isfile(temp_val_txt_path)):
#这里的train和val的划分采用随机数方式
#这里会更新txt的路径和图片的路径
ifrandom.random()<=tain_r:
txt_path=temp_train_txt_path
image_path=os.path.join(train_image_dir,image_name)
else:
txt_path=temp_val_txt_path
image_path=os.path.join(val_image_dir,image_name)
#将图片复制到指定路径
os.system('cp'+image_dir+''+image_path)
'''
由于via中的标注可能存在后续的添加的框,使得框的顺序会是乱的
如果不加下放的else内容,会使得后续的添加的框不能放在对应的txt中,而放到了上一个
循环的txt中
所以需要在else中判断,当前循环的框所对应的图片名与当前的txt名是否相同,如果不同,
6
说明出现上述问题
那么就需要重置txt
'''
else:
#判断当前循环的框所对应的图片名与当前的txt名是否相同
ifimage_name.split('.')[0]==image_name.split('/')[-1].split('.')[0]:
#判断重置的txt路径是在train中还是在val中
ifos.path.isfile(temp_train_txt_path):
txt_path=temp_train_txt_path
else:
txt_path=temp_val_txt_path
#向指定txt路径追加内容
withopen(txt_path,"a")asfile:#a,代表追加内容
file.write(xcyc_wh)
#循环读出所有json文件
forroot,dirs,filesinos.walk(Via_Dataset_dir,topdown=False):
fornameinfiles:
file_dir=os.path.join(root,name)
if'.json'inname:
file_json=open(file_dir,'r')
file_json_content=json.loads(file_json.read())
via2yolo(file_json_content,root)
file_json.close()
print(file_dir)
via2yolo1.py
#这一段代码是将via转化为yolo格式
#pythonvia2yolo1.py--riseHand_via_dataset./riseHand_via_dataset--riseHand_Dataset./riseHand_Dataset
--tain_r0.8
#注意这是via中只框选了举手这个动作,就是将框转化为yolo格式,行为默认为0
importos
importjson
importcv2
importrandom
importargparse
importshutil
parser=argparse.ArgumentParser()
parser.add_argument('--riseHand_via_dataset',default='./riseHand_via_dataset',type=str)
parser.add_argument('--riseHand_Dataset',default='./riseHand_Dataset',type=str)
parser.add_argument('--tain_r',default=0.65,type=float)
arg=parser.parse_args()
riseHand_via_dataset=arg.riseHand_via_dataset
#yolo数据集的存放位置Dataset_dir
riseHand_Dataset=arg.riseHand_Dataset
#清空riseHand_Dataset下的文件及文件夹
7
ifos.path.exists(riseHand_Dataset):
shutil.rmtree(riseHand_Dataset)
#在Dataset_dir下创建labelsimagestrainval
os.makedirs(riseHand_Dataset+'/labels/train')
os.makedirs(riseHand_Dataset+'/labels/val')
os.makedirs(riseHand_Dataset+'/images/train')
os.makedirs(riseHand_Dataset+'/images/val')
#训练集与验证集的比例,tain_r代表训练集的比例,1-tain_r代表验证集的比例
tain_r=arg.tain_r
#设置labelsimagestrainval的路径
train_label_dir=riseHand_Dataset+'/labels/train/'
val_label_dir=riseHand_Dataset+'/labels/val/'
train_image_dir=riseHand_Dataset+'/images/train/'
val_image_dir=riseHand_Dataset+'/images/val/'
#via2yolo函数是将via信息转化为yolo的格式
defvia2yolo(json,root):
#循环读出每一个框的信息
foriinjson['metadata']:
#从i中获取vid
vid=i.split('_')[0]
#获取对应的图片名字
image_name=json['file'][vid]['fname']
#获取图片的路径
image_dir=os.path.join(root,image_name)
#读取图片的高和宽
img=cv2.imread(image_dir)
h=img.shape[0]
w=img.shape[1]
#读取via中的坐标xywh,框的左上角坐标xy,与框的宽高
xywh=json['metadata'][i]['xy'][1:]
'''
将xywh转化为yolo的格式
第一个参数是0,代表举手这一个分类
第二个参数是,框的中心坐标x,归一化处理
第三个参数是,框的中心坐标y,归一化处理
第四个参数是,框的宽度w,归一化处理
第五个参数是,框的高度h,归一化处理
第六个参数是,换行
'''
xcyc_wh='0'+str((xywh[0]+xywh[2]/2)/w)+''+str((xywh[1]+xywh[3]/2)/h)+\
8
''+str(xywh[2]/w)+''+str(xywh[3]/h)+'\n'
#设置txt的train和val的路径
temp_train_txt_path=os.path.join(train_label_dir,image_name.split('.')[0]+'.txt')
temp_val_txt_path=os.path.join(val_label_dir,image_name.split('.')[0]+'.txt')
'''
判断当前的temp_train_txt_path或者temp_val_txt_path是否已经存在
如果不存在,就进入if中
不存在代表已经进入下一个图片的框了,需要创建一个新的txt
如果存在,就进入else中
'''
ifnot(os.path.isfile(temp_train_txt_path)oros.path.isfile(temp_val_txt_path)):
#这里的train和val的划分采用随机数方式
#这里会更新txt的路径和图片的路径
ifrandom.random()<=tain_r:
txt_path=temp_train_txt_path
image_path=os.path.join(train_image_dir,image_name)
else:
txt_path=temp_val_txt_path
image_path=os.path.join(val_image_dir,image_name)
#将图片复制到指定路径
shutil.copy(image_dir,image_path)
'''
由于via中的标注可能存在后续的添加的框,使得框的顺序会是乱的
如果不加下放的else内容,会使得后续的添加的框不能放在对应的txt中,而放到了上一个
循环的txt中
所以需要在else中判断,当前循环的框所对应的图片名与当前的txt名是否相同,如果不同,
说明出现上述问题
那么就需要重置txt
'''
else:
#判断当前循环的框所对应的图片名与当前的txt名是否相同
ifimage_name.split('.')[0]==image_name.split('/')[-1].split('.')[0]:
#判断重置的txt路径是在train中还是在val中
ifos.path.isfile(temp_train_txt_path):
txt_path=temp_train_txt_path
else:
txt_path=temp_val_txt_path
#向指定txt路径追加内容
withopen(txt_path,"a")asfile:#a,代表追加内容
file.write(xcyc_wh)
#循环读出所有json文件
forroot,dirs,filesinos.walk(riseHand_via_dataset,topdown=False):
9
fornameinfiles:
file_dir=os.path.join(root,name)
if'.json'inname:
file_json=open(file_dir,'r')
file_json_content=json.loads(file_json.read())
via2yolo(file_json_content,root)
file_json.close()
print(file_dir)
via2yolo2.py
#这一段代码是将via转化为yolo格式
#pythonvia2yolo2.py--RRW_via_Dataset./RRW_via_Dataset--RRW_Dataset./RRW_Dataset--tain_r0.8
#注意这是via中多个动作转化为yolo格式
#并且可以检查没有标注的框,并给出没有标注的图片
importos
importjson
importcv2
importrandom
importargparse
importshutil
parser=argparse.ArgumentParser()
parser.add_argument('--RRW_via_Dataset',default='./RRW_via_Dataset',type=str)
parser.add_argument('--RRW_Dataset',default='./RRW_Dataset',type=str)
parser.add_argument('--tain_r',default=0.8,type=float)
arg=parser.parse_args()
RRW_via_Dataset=arg.RRW_via_Dataset
#yolo数据集的存放位置Dataset_dir
RRW_Dataset=arg.RRW_Dataset
#删除Dataset_dir文件夹
ifos.path.exists(RRW_Dataset):
shutil.rmtree(RRW_Dataset)
#在Dataset_dir下创建labelsimagestrainval
os.makedirs(RRW_Dataset+'/labels/train')
os.makedirs(RRW_Dataset+'/labels/val')
os.makedirs(RRW_Dataset+'/images/train')
os.makedirs(RRW_Dataset+'/images/val')
#训练集与验证集的比例,tain_r代表训练集的比例,1-tain_r代表验证集的比例
tain_r=arg.tain_r
#设置labelsimagestrainval的路径
train_label_dir=RRW_Dataset+'/labels/train/'
val_label_dir=RRW_Dataset+'/labels/val/'
train_image_dir=RRW_Dataset+'/images/train/'
val_image_dir=RRW_Dataset+'/images/val/'
10
#via2yolo函数是将via信息转化为yolo的格式·
defvia2yolo(json,root):
#循环读出每一个框的信息
foriinjson['metadata']:
#从i中获取vid
vid=i.split('_')[0]
#获取对应的图片名字
image_name=json['file'][vid]['fname']
#获取图片的路径
image_dir=os.path.join(root,image_name)
#读取图片的高和宽
img=cv2.imread(image_dir)
h=img.shape[0]
w=img.shape[1]
#读取via中的坐标xywh,框的左上角坐标xy,与框的宽高
xywh=json['metadata'][i]['xy'][1:]
#获取动作的id
try:
action_id=json['metadata'][i]['av']['1']
exceptKeyError:
print(json['metadata'][i]['av'])
print("下面的图片中有没有标注的框")
print("image_name:",image_name)
input()
'''
将xywh转化为yolo的格式
第一个参数是0,代表举手这一个分类
第二个参数是,框的中心坐标x,归一化处理
第三个参数是,框的中心坐标y,归一化处理
第四个参数是,框的宽度w,归一化处理
第五个参数是,框的高度h,归一化处理
第六个参数是,换行
'''
xcyc_wh=action_id+''+str((xywh[0]+xywh[2]/2)/w)+''+str((xywh[1]+xywh[3]/2)/h)+\
''+str(xywh[2]/w)+''+str(xywh[3]/h)+'\n'
#设置txt的train和val的路径
temp_train_txt_path=os.path.join(train_label_dir,image_name.split('.')[0]+'.txt')
temp_val_txt_path=os.path.join(val_label_dir,image_name.split('.')[0]+'.txt')
'''
判断当前的temp_train_txt_path或者temp_val_txt_path是否已经存在
如果不存在,就进入if中
不存在代表已经进入下一个图片的框了,需要创建一个新的txt
如果存在,就进入else中
11
'''
ifnot(os.path.isfile(temp_train_txt_path)oros.path.isfile(temp_val_txt_path)):
#这里的train和val的划分采用随机数方式
#这里会更新txt的路径和图片的路径
ifrandom.random()<=tain_r:
txt_path=temp_train_txt_path
image_path=os.path.join(train_image_dir,image_name)
else:
txt_path=temp_val_txt_path
image_path=os.path.join(val_image_dir,image_name)
#将图片复制到指定路径
shutil.copy(image_dir,image_path)
'''
由于via中的标注可能存在后续的添加的框,使得框的顺序会是乱的
如果不加下放的else内容,会使得后续的添加的框不能放在对应的txt中,而放到了上一个
循环的txt中
所以需要在else中判断,当前循环的框所对应的图片名与当前的txt名是否相同,如果不同,
说明出现上述问题
那么就需要重置txt
'''
else:
#判断当前循环的框所对应的图片名与当前的txt名是否相同
ifimage_name.split('.')[0]==image_name.split('/')[-1].split('.')[0]:
#判断重置的txt路径是在train中还是在val中
ifos.path.isfile(temp_train_txt_path):
txt_path=temp_train_txt_path
else:
txt_path=temp_val_txt_path
#向指定txt路径追加内容
withopen(txt_path,"a")asfile:#a,代表追加内容
file.write(xcyc_wh)
#循环读出所有json文件
forroot,dirs,filesinos.walk(RRW_via_Dataset,topdown=False):
fornameinfiles:
file_dir=os.path.join(root,name)
if'.json'inname:
file_json=open(file_dir,'r')
file_json_content=json.loads(file_json.read())
via2yolo(file_json_content,root)
file_json.close()
print(file_dir)
viaextendaction1.py
#这段代码是对举手的数据集进行via标注扩展,扩展更多动作
12
#pythonviaExtendAction1.py--riseHand_via_dataset./riseHand_via_dataset
--RRW_via_Dataset./RRW_via_Dataset
importos
importjson
importargparse
importshutil
parser=argparse.ArgumentParser()
parser.add_argument('--riseHand_via_dataset',default='./riseHand_via_dataset',type=str)
parser.add_argument('--RRW_via_Dataset',default='./RRW_via_Dataset',type=str)
arg=parser.parse_args()
#Dataset_dir是via举手数据集的位置
riseHand_via_dataset=arg.riseHand_via_dataset
#newDataset_dir是扩展后的via数据集的位置,RRW分别代表举手、看书、写字
RRW_via_Dataset=arg.RRW_via_Dataset
#扩展数据集
attributes_dict={
'1':dict(aname='动作',type=3,options={'0':'举手','1':'看书','2':'写字'},default_option_id="",
anchor_id='FILE1_Z0_XY1'),
}
#清空RRW_via_Dataset下的文件及文件夹
ifos.path.exists(RRW_via_Dataset):
shutil.rmtree(RRW_via_Dataset)
#将riseHand_via_dataset复制
shutil.copytree(riseHand_via_dataset,RRW_via_Dataset)
forroot,dirs,filesinos.walk(riseHand_via_dataset,topdown=False):
fornameinfiles:
if'.json'inname:
json_path=os.path.join(root,name)
withopen(json_path)asf:
json_data=json.load(f)
#添加扩展动作
json_data['attribute']=attributes_dict
foreleinjson_data['metadata']:
#添加举手的标签
json_data['metadata'][ele]['av']={"1":"0"}
new_json_pathx=json_path.replace(riseHand_via_dataset,RRW_via_Dataset)
new_json=open(new_json_pathx,'w')
new_json.write(json.dumps(json_data))
visual.py
#pythonvisual.py--yolo_Dataset./riseHand_Dataset--Visual_dir./Visual
#本代码的作用可视化yolo数据
importos
importnumpyasnp
importcv2
13
importargparse
importshutil
parser=argparse.ArgumentParser()
parser.add_argument('--yolo_Dataset',default='./riseHand_Dataset',type=str)
parser.add_argument('--Visual_dir',default='./Visual',type=str)
arg=parser.parse_args()
yolo_Dataset=arg.yolo_Dataset
Visual_dir=arg.Visual_dir
#清空Visual_dir下的文件及文件夹
ifos.path.exists(Visual_dir):
shutil.rmtree(Visual_dir)
#在Visual_dir下创建labelsimagestrainval
os.makedirs(Visual_dir)
train_label_path=os.path.join(yolo_Dataset,'labels/train')
train_image_path=os.path.join(yolo_Dataset,'images/train')
val_label_path=os.path.join(yolo_Dataset,'labels/val')
val_image_path=os.path.join(yolo_Dataset,'images/val')
#坐标转换,原始存储的是YOLOv5格式
#Convertnx4boxesfrom[x,y,w,h]normalizedto[x1,y1,x2,y2]wherexy1=top-left,xy2=bottom-right
defxywh2xyxy(x,w1,h1,img):
labels=['s1','s2','s3']
label,x,y,w,h=x
#边界框反归一化
x_t=x*w1
y_t=y*h1
w_t=w*w1
h_t=h*h1
#计算坐标
top_left_x=x_t-w_t/2
top_left_y=y_t-h_t/2
bottom_right_x=x_t+w_t/2
bottom_right_y=y_t+h_t/2
returnint(top_left_x),int(top_left_y),int(bottom_right_x),int(bottom_right_y)
#将train中的可视化
forroot,dirs,filesinos.walk(train_label_path,topdown=False):
#循环遍历出所有的txt
fornameinfiles:
txt_path=os.path.join(root,name)
if'.txt'inname:
file_txt=open(txt_path,'r')
14
#读出txt中的数据
lb=np.array([x.split()forxinfile_txt.read().strip().splitlines()],dtype=np.float32)#labels
image_name=name.split('.')[0]+'.png'
image_path=os.path.join(train_image_path,image_name)
#读取图像文件
img=cv2.imread(image_path)
h,w=img.shape[:2]
forxinlb:
#反归一化并得到左上和右下坐标,画出矩形框
x1,y1,x2,y2=xywh2xyxy(x,w,h,img)
#绘图rectangle()函数需要坐标为整数,xywh2xyxy返回值已经是整数了。
cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),2)
visual_img_path=os.path.join(Visual_dir,image_name)
#将处理后的图片存储
cv2.imwrite(visual_img_path,img)
#将val中的可视化
forroot,dirs,filesinos.walk(val_label_path,topdown=False):
fornameinfiles:
txt_path=os.path.join(root,name)
if'.txt'inname:
file_txt=open(txt_path,'r')
lb=np.array([x.split()forxinfile_txt.read().strip().splitlines()],dtype=np.float32)#labels
image_name=name.split('.')[0]+'.png'
image_path=os.path.join(val_image_path,image_name)
#读取图像文件
img=cv2.imread(image_path)
h,w=img.shape[:2]
forxinlb:
#反归一化并得到左上和右下坐标,画出矩形框
x1,y1,x2,y2=xywh2xyxy(x,w,h,img)
#绘图rectangle()函数需要坐标为整数,xywh2xyxy返回值已经是整数了。
cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),2)
visual_img_path=os.path.join(Visual_dir,image_name)
cv2.imwrite(visual_img_path,img)
via3_tool.py
#-*-coding:utf-8-*-
#文件格式参考:
/vgg/via/-/blob/via-3.x.y/via-3.x.y/CodeDoc.md#structure-of-via-project-json-file
importjson
15
fromcollectionsimportdefaultdict
classVia3Json(object):
def__init_load(self,json_path):
withopen(json_path,'r',encoding='utf-8')asjson_fd:
self.ann_dict=json.load(json_fd)
jects=self.ann_dict['project']
self.configs=self.ann_dict['config']
self.attributes=self.ann_dict['attribute']
self.views=self.ann_dict['view']
self.metadatas=self.ann_dict['metadata']
self.files=self.ann_dict['file']
vid2metadatas=defaultdict(list)
formetadata_keyinself.metadatas:
vid=self.metadatas[metadata_key]['vid']
ifvidinvid2metadatas:
vid2metadatas[vid].append(self.metadatas[metadata_key])
else:
vid2metadatas[vid]=[self.metadatas[metadata_key]]
self.vid2metadatas=vid2metadatas
def__init_dump(self,json_path):
self.json_path=json_path
jects=dict()
self.configs=dict()
self.attributes=dict()
self.files=dict()
self.metadatas=dict()
self.views=dict()
def__init__(self,json_path,mode='load'):
ifmode=='load':
self.__init_load(json_path)
elifmode=='dump':
self.__init_dump(json_path)
else:
raiseException('modecan
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年常州工程职业技术学院单招职业适应性测试题库附答案详解(培优)
- 2026镍基合金材料微观缺陷检测与控制技术研究报告
- 2026年娄底幼儿师范高等专科学校单招职业倾向性考试题库附答案详解(典型题)
- 2026年四川财经职业学院单招职业技能考试题库有完整答案详解
- 2026年宁波大学科学技术学院单招职业倾向性考试题库附参考答案详解(巩固)
- 2026年天门职业学院单招职业倾向性考试题库及答案详解(夺冠系列)
- 2026年能源智能微电网报告
- 2026年日化行业绿色经济创新报告
- 2025江西抚州市市属国有企业招聘员工入闱人员及笔试历年常考点试题专练附带答案详解
- 2025江西吉安全民健身体育中心运营管理有限公司招聘工作人员2人笔试历年典型考点题库附带答案详解
- 2025年广东广州开发区财政投资建设项目管理中心第二批公开招聘初级雇员5人事业单位考试押题密卷笔试历年典型考题(历年真题考点)解题思路附带答案详解
- 纪念币反假培训课件
- 《建筑结构检测技术标准》
- (新教材)2026年人教版八年级下册数学 21.1 四边形及多边形 课件
- 2026年辽宁医药职业学院单招职业技能考试题库含答案
- 职场压力与心理调适-洞察及研究
- 证券基础知识入门
- 上市公司销售合同范本
- 长城专题课件
- DB31T+1487-2024国际医疗服务规范
- 云南的士从业资格证考试及答案解析
评论
0/150
提交评论