将caltech数组集做成VOC格式
一、先下载caltech数据集
二、格式转换代码将 ".seq" 转换为 ".jpg" 文件 ( https://github.com/mitmul/caltech-pedestrian-dataset-converter.git)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #!/usr/bin/env python # -*- coding: utf-8 -*- import os import glob import cv2 as cv def save_img(dname, fn, i, frame): cv.imwrite( '{}/{}_{}_{}.png' . format ( out_dir, os.path. basename (dname), os.path. basename (fn). split ( '.' )[0], i), frame) out_dir = 'data/images' if not os.path.exists(out_dir): os.makedirs(out_dir) for dname in sorted(glob.glob( 'data/set*' )): for fn in sorted(glob.glob( '{}/*.seq' . format (dname))): cap = cv.VideoCapture(fn) i = 0 while True: ret, frame = cap. read () if not ret: break save_img(dname, fn, i, frame) i += 1 print(fn) |
三、将".vbb" 文件转化为 二进制文件文件(需要依赖code3.2.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | maindir = '/home/user/Downloads/caltech_data_set/data-USA/' ; subdir = dir ( maindir ); for i = 1 : length( subdir ) if ( isequal( subdir( i ).name, '.' )||... isequal( subdir( i ).name, '..' )||... ~subdir( i ).isdir) continue ; end % subdirpath = fullfile( maindir, subdir( i ).name, '' ); % dat = dir ( subdirpath ); % % for j = 1 : length( dat ) % datpath = fullfile( maindir, subdir( i ).name, dat( j ).name); % fid = fopen( datpath ); % % end if ((subdir(i).isdir && isequal(subdir(i).name(1:3), 'set' ))) tmp = fullfile(maindir, subdir(i).name); ssdir = dir (tmp); for j = 1 : length( ssdir ) if (ssdir(j).isdir) if ( isequal( ssdir( j ).name, '.' )||... isequal( ssdir( j ).name, '..' )||... ~ssdir( j ).isdir) continue ; end vName1 = fullfile(subdir(i).name, ssdir(j).name); fprintf(vName1); fnm = [subdir(i).name , ssdir(j).name]; fprintf(fnm); vbb_to_txtt(vName1, fnm); fprintf(vName1) end end % vName1 = fullfile( 'set00' , subdir(i).name); % fprintf(vName1); end end function vbb_to_txtt(vName, fnm) % vName = 'set01/V000' A = vbb( 'vbbLoad' , [dbInfo '/annotations/' vName] ); path = '/home/user/Downloads/caltech_data_set/data/annotations' ; %fnm = 'set01-V000.txt' ; c=fopen([path '-' fnm], 'w' ); for i = 1:A.nFrame iframe = A.objLists(1,i); iframe_data = iframe{1,1}; n1length = length(iframe_data); for j = 1:n1length iframe_dataj = iframe_data(j); if iframe_dataj.pos(1) ~= 0 %pos posv fprintf(c, '%d %f %f %f %f\n' , i, iframe_dataj.pos(1),iframe_dataj.pos(2),iframe_dataj.pos(3),iframe_dataj.pos(4)); end end end fclose(c); end |
四、将生成二进制文件中的标注框写成VOC格式的XML文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | #!/usr/bin/env python # coding:utf-8 #from xml.etree.ElementTree import Element, SubElement, tostring from lxml.etree import Element, SubElement, tostring import pprint from xml.dom.minidom import parseString import os def mkdir (path): import os path = path.strip() path = path.rstrip( "\\" ) isExists = os.path.exists(path) if not isExists: os.makedirs(path) print path + 'ok' return True else : print path + 'failed!' return False def generate_xml(file_info, obj): node_root = Element( 'annotation' ) node_folder = SubElement(node_root, 'folder' ) node_folder.text = file_info[0] node_filename = SubElement(node_root, 'filename' ) node_filename.text = file_info[1] node_size = SubElement(node_root, 'size' ) node_width = SubElement(node_size, 'width' ) node_width.text = '640' node_height = SubElement(node_size, 'height' ) node_height.text = '480' node_depth = SubElement(node_size, 'depth' ) node_depth.text = '3' for obj_i in obj: print obj_i node_object = SubElement(node_root, 'object' ) node_name = SubElement(node_object, 'name' ) #node_name.text = 'mouse' node_name.text = 'person' node_bndbox = SubElement(node_object, 'bndbox' ) node_xmin = SubElement(node_bndbox, 'xmin' ) #node_xmin.text = '99' node_xmin.text = obj_i[ 'xmin' ] node_ymin = SubElement(node_bndbox, 'ymin' ) #node_ymin.text = '358' node_ymin.text = obj_i[ 'ymin' ] node_xmax = SubElement(node_bndbox, 'xmax' ) #node_xmax.text = '135' node_xmax.text = obj_i[ 'xmax' ] node_ymax = SubElement(node_bndbox, 'ymax' ) #node_ymax.text = '375' node_ymax.text = obj_i[ 'ymax' ] xml = tostring(node_root, pretty_print=True) #格式化显示,该换行的换行 dom = parseString(xml) file_root = '/home/user/Downloads/caltech_data_set/data_test/' file_name = file_root + file_info[0]; mkdir (file_name) fw = open (file_name+ "/" +file_info[1]. split ( '.' )[0]+ ".xml" , 'a+' ) fw.write(xml) print "xml _ ok" fw.close() #for debug #print xml def printPath(level, path): global allFileNum '' '' ' 打印一个目录下的所有文件夹和文件 '' ' # 所有文件夹,第一个字段是次目录的级别 dirList = [] # 所有文件 fileList = [] # 返回一个列表,其中包含在目录条目的名称(google翻译) files = os.listdir(path) # 先添加目录级别 dirList.append(str(level)) for f in files: if (os.path.isdir(path + '/' + f)): # 排除隐藏文件夹。因为隐藏文件夹过多 if (f[0] == '.' ): pass else : # 添加非隐藏文件夹 dirList.append(f) if (os.path.isfile(path + '/' + f)): # 添加文件 fileList.append(f) # 当一个标志使用,文件夹列表第一个级别不打印 i_dl = 0 for dl in dirList: if (i_dl == 0): i_dl = i_dl + 1 else : # 打印至控制台,不是第一个的目录 print '-' * (int(dirList[0])), dl # 打印目录下的所有文件夹和文件,目录级别+1 printPath((int(dirList[0]) + 1), path + '/' + dl) print fileList for fl in fileList: # 打印文件 #print '-' * (int(dirList[0])), fl # 随便计算一下有多少个文件 #allFileNum = allFileNum + 1 "" " 操作文件进行读写 "" " print fl[12:17],fl[17:21] file_info = [] file_info.append(fl[12:17]+ '/' +fl[17:21]) print file_info print path file_name = path+ "/" +fl fw = open (file_name, 'r' ); line_content = fw.readlines() fw.close() print line_content tmp = -1 obj = [] con_len = len(line_content) try: string = line_content[0]. split ( " " ) tmp = int(string[0]) except Exception: continue file_info.append(str(tmp) + '.jpg' ) xmin = str(int(float(string[1]))) ymin = str(int(float(string[2]))) xmax = str(int(float(string[1]) + float(string[3]))) ymax = str(int(float(string[2]) + float(string[4]))) dict1 = {} dict1[ "xmin" ] = xmin dict1[ "ymin" ] = ymin dict1[ "xmax" ] = xmax dict1[ "ymax" ] = ymax obj.append(dict1) for con_i in xrange(1, con_len): string = line_content[con_i]. split ( " " ) tmp1 = int(string[0]) if tmp == tmp1: xmin = str(int(float(string[1]))) ymin = str(int(float(string[2]))) xmax = str(int(float(string[1]) + float(string[3]))) ymax = str(int(float(string[2]) + float(string[4]))) dict1 = {} dict1[ "xmin" ] = xmin dict1[ "ymin" ] = ymin dict1[ "xmax" ] = xmax dict1[ "ymax" ] = ymax obj.append(dict1) elif tmp1 > 0: generate_xml(file_info, obj) obj = [] tmp = tmp1 file_info[1] = str(tmp1) + ".jpg" xmin = str(int(float(string[1]))) ymin = str(int(float(string[2]))) xmax = str(int(float(string[1]) + float(string[3]))) ymax = str(int(float(string[2]) + float(string[4]))) dict1 = {} dict1[ "xmin" ] = xmin dict1[ "ymin" ] = ymin dict1[ "xmax" ] = xmax dict1[ "ymax" ] = ymax obj.append(dict1) continue def read_annotations_generate_fileinfo_obj(file_path): pass if __name__== "__main__" : # # file_info = ['set00/V000', '1.jpg'] # # obj = [] # obj1 = {"xmin":"1", "ymin":"1", "xmax":"5", "ymax":"5"} # obj2 = {"xmin":"2", "ymin":"2", "xmax":"6", "ymax":"6"} # obj.append(obj1) # obj.append(obj2) # # generate_xml(file_info, obj) # printPath(1, "/home/user/Downloads/caltech_data_set/data_old" ) |
五、使用脚本,利用xml文件,生成train.txt trainval.txt test.txt 等文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import os import random def folder_struct(level, path): global allFileNum dirList = [] fileList = [] files = os.listdir(path) dirList.append(str(level)) for f in files: if (os.path.isdir(path + '/' + f)): if f[0] != '.' : dirList.append(f) if (os.path.isfile(path + '/' + f)): fileList.append(f) i_dl = 0 for dl in dirList: if i_dl == 0: i_dl = i_dl + 1 else : #print '-' * (int(dirList[0])), dl folder_struct((int(dirList[0]) + 1), path+ '/' +dl) print dirList # print fileList # print dirList for fl in fileList: #print fl[12:17], fl[17:21] file_info = (fl[12:17] + '/' + fl[17:21]) print file_info generate_txt(file_info) pass def generate_txt(xml_folder): trainval_percent = 0.66 train_percent = 0.5 folder_root = '/home/user/Desktop/VOC/' xmlfilepath = folder_root + 'Annotations/' +xml_folder txtsavepath = folder_root + 'ImageSets/Main' try: total_xml = os.listdir(xmlfilepath) #print total_xml num = len(total_xml) #print num list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr ) ftrainval = open (folder_root + 'ImageSets/Main/trainval.txt' , 'aw' ) ftest = open (folder_root + 'ImageSets/Main/test.txt' , 'aw' ) ftrain = open (folder_root + 'ImageSets/Main/train.txt' , 'aw' ) fval = open (folder_root + 'ImageSets/Main/val.txt' , 'aw' ) folder_name = xmlfilepath[-10:] + '/' print folder_name for i in list: name = folder_name + total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else : fval.write(name) else : ftest.write(name) ftrainval.close() ftrain.close() fval.close() ftest.close() except Exception: pass #用来便利所有文件夹名的,没有用遍历文件夹名的方法,而是用一开始生成的注释文件的名字去遍历文件夹名。。。 folder_struct(1, "/home/user/Downloads/caltech_data_set/data_old" ) |
在具体训练的时候,需要用0-5作为训练集,然后用6-10作为测试集
在跑的过程中,可能会有标注越界的问题,在voc_eval.py 和pascal_voc.py中进行更改就好了。推荐博客
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步