【源码】基于via的学生行为数据标注与yolov7检测系统_第1页
【源码】基于via的学生行为数据标注与yolov7检测系统_第2页
【源码】基于via的学生行为数据标注与yolov7检测系统_第3页
【源码】基于via的学生行为数据标注与yolov7检测系统_第4页
【源码】基于via的学生行为数据标注与yolov7检测系统_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论